From 484f32f3e4e34686cf27184be53c97d64fe86513 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tur=C3=A1nszki=20J=C3=A1nos?= Date: Tue, 25 Jul 2023 09:59:59 +0200 Subject: [PATCH] shader buffer refactor; vulkan mesh shader fixes; (#713) --- .github/workflows/build-nightly.yml | 2 +- .github/workflows/build-pr.yml | 2 +- .github/workflows/build.yml | 2 +- WickedEngine/Utility/spirv_reflect.h | 192 +++++++++++++++--- .../shaders/ShaderInterop_EmittedParticle.h | 7 +- WickedEngine/shaders/bvh_primitivesCS.hlsl | 17 +- WickedEngine/shaders/emittedparticleHF.hlsli | 10 +- WickedEngine/shaders/emittedparticleMS.hlsl | 50 +++-- WickedEngine/shaders/emittedparticleVS.hlsl | 12 +- .../shaders/emittedparticle_emitCS.hlsl | 162 +++++++-------- .../shaders/emittedparticle_simulateCS.hlsl | 23 +-- WickedEngine/shaders/globals.hlsli | 115 ++++++++--- WickedEngine/shaders/hairparticleVS.hlsl | 8 +- .../shaders/hairparticle_simulateCS.hlsl | 67 +++--- WickedEngine/shaders/impostorVS.hlsl | 4 +- WickedEngine/shaders/impostor_prepareCS.hlsl | 4 +- WickedEngine/shaders/objectHF.hlsli | 35 ++-- WickedEngine/shaders/skinningCS.hlsl | 89 +++----- WickedEngine/shaders/surfaceHF.hlsli | 111 +++++----- WickedEngine/shaders/tonemapCS.hlsl | 48 +++-- WickedEngine/wiEmittedParticle.cpp | 15 +- WickedEngine/wiGraphicsDevice_Vulkan.cpp | 27 ++- WickedEngine/wiGraphicsDevice_Vulkan.h | 1 + WickedEngine/wiHairParticle.cpp | 12 +- WickedEngine/wiRenderer.cpp | 2 +- WickedEngine/wiScene.cpp | 16 +- WickedEngine/wiScene_Components.cpp | 39 ++-- WickedEngine/wiScene_Components.h | 118 ++++++----- WickedEngine/wiVersion.cpp | 2 +- 29 files changed, 685 insertions(+), 507 deletions(-) diff --git a/.github/workflows/build-nightly.yml b/.github/workflows/build-nightly.yml index 464aa9941..85d59c7e6 100644 --- a/.github/workflows/build-nightly.yml +++ b/.github/workflows/build-nightly.yml @@ -102,7 +102,7 @@ jobs: - name: Package Content uses: actions/upload-artifact@v2 with: - name: Additional Content + name: Content path: | Content/models Content/scripts diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 8c83f72f5..21a5ad050 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -102,7 +102,7 @@ jobs: - name: Package Content uses: actions/upload-artifact@v2 with: - name: Additional Content + name: Content path: | Content/models Content/scripts diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3079a81e7..f8b327674 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -103,7 +103,7 @@ jobs: - name: Package Content uses: actions/upload-artifact@v2 with: - name: Additional Content + name: Content path: | Content/models Content/scripts diff --git a/WickedEngine/Utility/spirv_reflect.h b/WickedEngine/Utility/spirv_reflect.h index 3abc335ee..12ef2b1e3 100644 --- a/WickedEngine/Utility/spirv_reflect.h +++ b/WickedEngine/Utility/spirv_reflect.h @@ -1,5 +1,5 @@ /* - Copyright 2017-2018 Google Inc. + Copyright 2017-2022 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -30,7 +30,12 @@ VERSION HISTORY #ifndef SPIRV_REFLECT_H #define SPIRV_REFLECT_H +#if defined(SPIRV_REFLECT_USE_SYSTEM_SPIRV_H) +#include +#else #include "./include/spirv/unified1/spirv.h" +#endif + #include #include @@ -74,8 +79,28 @@ typedef enum SpvReflectResult { SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_BLOCK_MEMBER_REFERENCE, SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_ENTRY_POINT, SPV_REFLECT_RESULT_ERROR_SPIRV_INVALID_EXECUTION_MODE, + SPV_REFLECT_RESULT_ERROR_SPIRV_MAX_RECURSIVE_EXCEEDED, } SpvReflectResult; +/*! @enum SpvReflectModuleFlagBits + +SPV_REFLECT_MODULE_FLAG_NO_COPY - Disables copying of SPIR-V code + when a SPIRV-Reflect shader module is created. It is the + responsibility of the calling program to ensure that the pointer + remains valid and the memory it's pointing to is not freed while + SPIRV-Reflect operations are taking place. Freeing the backing + memory will cause undefined behavior or most likely a crash. + This is flag is intended for cases where the memory overhead of + storing the copied SPIR-V is undesirable. + +*/ +typedef enum SpvReflectModuleFlagBits { + SPV_REFLECT_MODULE_FLAG_NONE = 0x00000000, + SPV_REFLECT_MODULE_FLAG_NO_COPY = 0x00000001, +} SpvReflectModuleFlagBits; + +typedef uint32_t SpvReflectModuleFlags; + /*! @enum SpvReflectTypeFlagBits */ @@ -95,12 +120,20 @@ typedef enum SpvReflectTypeFlagBits { SPV_REFLECT_TYPE_FLAG_EXTERNAL_MASK = 0x00FF0000, SPV_REFLECT_TYPE_FLAG_STRUCT = 0x10000000, SPV_REFLECT_TYPE_FLAG_ARRAY = 0x20000000, + SPV_REFLECT_TYPE_FLAG_REF = 0x40000000, } SpvReflectTypeFlagBits; typedef uint32_t SpvReflectTypeFlags; /*! @enum SpvReflectDecorationBits +NOTE: HLSL row_major and column_major decorations are reversed + in SPIR-V. Meaning that matrices declrations with row_major + will get reflected as column_major and vice versa. The + row and column decorations get appied during the compilation. + SPIRV-Reflect reads the data as is and does not make any + attempt to correct it to match what's in the source. + */ typedef enum SpvReflectDecorationFlagBits { SPV_REFLECT_DECORATION_NONE = 0x00000000, @@ -112,6 +145,8 @@ typedef enum SpvReflectDecorationFlagBits { SPV_REFLECT_DECORATION_NOPERSPECTIVE = 0x00000020, SPV_REFLECT_DECORATION_FLAT = 0x00000040, SPV_REFLECT_DECORATION_NON_WRITABLE = 0x00000080, + SPV_REFLECT_DECORATION_RELAXED_PRECISION = 0x00000100, + SPV_REFLECT_DECORATION_NON_READABLE = 0x00000200, } SpvReflectDecorationFlagBits; typedef uint32_t SpvReflectDecorationFlags; @@ -132,6 +167,18 @@ typedef enum SpvReflectResourceType { */ typedef enum SpvReflectFormat { SPV_REFLECT_FORMAT_UNDEFINED = 0, // = VK_FORMAT_UNDEFINED + SPV_REFLECT_FORMAT_R16_UINT = 74, // = VK_FORMAT_R16_UINT + SPV_REFLECT_FORMAT_R16_SINT = 75, // = VK_FORMAT_R16_SINT + SPV_REFLECT_FORMAT_R16_SFLOAT = 76, // = VK_FORMAT_R16_SFLOAT + SPV_REFLECT_FORMAT_R16G16_UINT = 81, // = VK_FORMAT_R16G16_UINT + SPV_REFLECT_FORMAT_R16G16_SINT = 82, // = VK_FORMAT_R16G16_SINT + SPV_REFLECT_FORMAT_R16G16_SFLOAT = 83, // = VK_FORMAT_R16G16_SFLOAT + SPV_REFLECT_FORMAT_R16G16B16_UINT = 88, // = VK_FORMAT_R16G16B16_UINT + SPV_REFLECT_FORMAT_R16G16B16_SINT = 89, // = VK_FORMAT_R16G16B16_SINT + SPV_REFLECT_FORMAT_R16G16B16_SFLOAT = 90, // = VK_FORMAT_R16G16B16_SFLOAT + SPV_REFLECT_FORMAT_R16G16B16A16_UINT = 95, // = VK_FORMAT_R16G16B16A16_UINT + SPV_REFLECT_FORMAT_R16G16B16A16_SINT = 96, // = VK_FORMAT_R16G16B16A16_SINT + SPV_REFLECT_FORMAT_R16G16B16A16_SFLOAT = 97, // = VK_FORMAT_R16G16B16A16_SFLOAT SPV_REFLECT_FORMAT_R32_UINT = 98, // = VK_FORMAT_R32_UINT SPV_REFLECT_FORMAT_R32_SINT = 99, // = VK_FORMAT_R32_SINT SPV_REFLECT_FORMAT_R32_SFLOAT = 100, // = VK_FORMAT_R32_SFLOAT @@ -197,13 +244,15 @@ typedef enum SpvReflectShaderStageFlagBits { SPV_REFLECT_SHADER_STAGE_FRAGMENT_BIT = 0x00000010, // = VK_SHADER_STAGE_FRAGMENT_BIT SPV_REFLECT_SHADER_STAGE_COMPUTE_BIT = 0x00000020, // = VK_SHADER_STAGE_COMPUTE_BIT SPV_REFLECT_SHADER_STAGE_TASK_BIT_NV = 0x00000040, // = VK_SHADER_STAGE_TASK_BIT_NV + SPV_REFLECT_SHADER_STAGE_TASK_BIT_EXT = SPV_REFLECT_SHADER_STAGE_TASK_BIT_NV, // = VK_SHADER_STAGE_CALLABLE_BIT_EXT SPV_REFLECT_SHADER_STAGE_MESH_BIT_NV = 0x00000080, // = VK_SHADER_STAGE_MESH_BIT_NV - SPV_REFLECT_SHADER_STAGE_RAYGEN_BIT_KHR = 0x00000100, // VK_SHADER_STAGE_RAYGEN_BIT_KHR - SPV_REFLECT_SHADER_STAGE_ANY_HIT_BIT_KHR = 0x00000200, // VK_SHADER_STAGE_ANY_HIT_BIT_KHR - SPV_REFLECT_SHADER_STAGE_CLOSEST_HIT_BIT_KHR = 0x00000400, // VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR - SPV_REFLECT_SHADER_STAGE_MISS_BIT_KHR = 0x00000800, // VK_SHADER_STAGE_MISS_BIT_KHR - SPV_REFLECT_SHADER_STAGE_INTERSECTION_BIT_KHR = 0x00001000, // VK_SHADER_STAGE_INTERSECTION_BIT_KHR - SPV_REFLECT_SHADER_STAGE_CALLABLE_BIT_KHR = 0x00002000, // VK_SHADER_STAGE_CALLABLE_BIT_KHR + SPV_REFLECT_SHADER_STAGE_MESH_BIT_EXT = SPV_REFLECT_SHADER_STAGE_MESH_BIT_NV, // = VK_SHADER_STAGE_CALLABLE_BIT_EXT + SPV_REFLECT_SHADER_STAGE_RAYGEN_BIT_KHR = 0x00000100, // = VK_SHADER_STAGE_RAYGEN_BIT_KHR + SPV_REFLECT_SHADER_STAGE_ANY_HIT_BIT_KHR = 0x00000200, // = VK_SHADER_STAGE_ANY_HIT_BIT_KHR + SPV_REFLECT_SHADER_STAGE_CLOSEST_HIT_BIT_KHR = 0x00000400, // = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR + SPV_REFLECT_SHADER_STAGE_MISS_BIT_KHR = 0x00000800, // = VK_SHADER_STAGE_MISS_BIT_KHR + SPV_REFLECT_SHADER_STAGE_INTERSECTION_BIT_KHR = 0x00001000, // = VK_SHADER_STAGE_INTERSECTION_BIT_KHR + SPV_REFLECT_SHADER_STAGE_CALLABLE_BIT_KHR = 0x00002000, // = VK_SHADER_STAGE_CALLABLE_BIT_KHR } SpvReflectShaderStageFlagBits; @@ -259,9 +308,20 @@ typedef struct SpvReflectImageTraits { SpvImageFormat image_format; } SpvReflectImageTraits; +typedef enum SpvReflectArrayDimType { + SPV_REFLECT_ARRAY_DIM_RUNTIME = 0, // OpTypeRuntimeArray + SPV_REFLECT_ARRAY_DIM_SPEC_CONSTANT = 0xFFFFFFFF // specialization constant +} SpvReflectArrayDimType; + typedef struct SpvReflectArrayTraits { uint32_t dims_count; + // Each entry is either: + // - specialization constant dimension + // - OpTypeRuntimeArray + // - the array length otherwise uint32_t dims[SPV_REFLECT_MAX_ARRAY_DIMS]; + // Stores Ids for dimensions that are specialization constants + uint32_t spec_constant_op_ids[SPV_REFLECT_MAX_ARRAY_DIMS]; uint32_t stride; // Measured in bytes } SpvReflectArrayTraits; @@ -271,12 +331,13 @@ typedef struct SpvReflectBindingArrayTraits { } SpvReflectBindingArrayTraits; /*! @struct SpvReflectTypeDescription - + @brief Information about an OpType* instruction */ typedef struct SpvReflectTypeDescription { uint32_t id; SpvOp op; const char* type_name; + // Non-NULL if type is member of a struct const char* struct_member_name; SpvStorageClass storage_class; SpvReflectTypeFlags type_flags; @@ -288,18 +349,25 @@ typedef struct SpvReflectTypeDescription { SpvReflectArrayTraits array; } traits; + // If underlying type is a struct (ex. array of structs) + // this gives access to the OpTypeStruct + struct SpvReflectTypeDescription* struct_type_description; + + // @deprecated use struct_type_description instead uint32_t member_count; + // @deprecated use struct_type_description instead struct SpvReflectTypeDescription* members; } SpvReflectTypeDescription; /*! @struct SpvReflectInterfaceVariable - + @brief The OpVariable that is either an Input or Output to the module */ typedef struct SpvReflectInterfaceVariable { uint32_t spirv_id; const char* name; uint32_t location; + uint32_t component; SpvStorageClass storage_class; const char* semantic; SpvReflectDecorationFlags decoration_flags; @@ -329,6 +397,7 @@ typedef struct SpvReflectInterfaceVariable { typedef struct SpvReflectBlockVariable { uint32_t spirv_id; const char* name; + // For Push Constants, this is the lowest offset of all memebers uint32_t offset; // Measured in bytes uint32_t absolute_offset; // Measured in bytes uint32_t size; // Measured in bytes @@ -342,6 +411,11 @@ typedef struct SpvReflectBlockVariable { struct SpvReflectBlockVariable* members; SpvReflectTypeDescription* type_description; + + struct { + uint32_t offset; + } word_offset; + } SpvReflectBlockVariable; /*! @struct SpvReflectDescriptorBinding @@ -369,6 +443,8 @@ typedef struct SpvReflectDescriptorBinding { uint32_t binding; uint32_t set; } word_offset; + + SpvReflectDecorationFlags decoration_flags; } SpvReflectDescriptorBinding; /*! @struct SpvReflectDescriptorSet @@ -390,10 +466,10 @@ typedef struct SpvReflectEntryPoint { SpvExecutionModel spirv_execution_model; SpvReflectShaderStageFlagBits shader_stage; - uint32_t input_variable_count; - SpvReflectInterfaceVariable** input_variables; - uint32_t output_variable_count; - SpvReflectInterfaceVariable** output_variables; + uint32_t input_variable_count; + SpvReflectInterfaceVariable** input_variables; + uint32_t output_variable_count; + SpvReflectInterfaceVariable** output_variables; uint32_t interface_variable_count; SpvReflectInterfaceVariable* interface_variables; @@ -405,13 +481,26 @@ typedef struct SpvReflectEntryPoint { uint32_t used_push_constant_count; uint32_t* used_push_constants; + uint32_t execution_mode_count; + SpvExecutionMode* execution_modes; + struct LocalSize { uint32_t x; uint32_t y; uint32_t z; } local_size; + uint32_t invocations; // valid for geometry + uint32_t output_vertices; // valid for geometry, tesselation } SpvReflectEntryPoint; +/*! @struct SpvReflectCapability + +*/ +typedef struct SpvReflectCapability { + SpvCapability value; + uint32_t word_offset; +} SpvReflectCapability; + /*! @struct SpvReflectShaderModule */ @@ -425,6 +514,8 @@ typedef struct SpvReflectShaderModule { uint32_t source_language_version; const char* source_file; const char* source_source; + uint32_t capability_count; + SpvReflectCapability* capabilities; SpvExecutionModel spirv_execution_model; // Uses value(s) from first entry point SpvReflectShaderStageFlagBits shader_stage; // Uses value(s) from first entry point uint32_t descriptor_binding_count; // Uses value(s) from first entry point @@ -441,6 +532,7 @@ typedef struct SpvReflectShaderModule { SpvReflectBlockVariable* push_constant_blocks; // Uses value(s) from first entry point struct Internal { + SpvReflectModuleFlags module_flags; size_t spirv_size; uint32_t* spirv_code; uint32_t spirv_word_count; @@ -469,6 +561,22 @@ SpvReflectResult spvReflectCreateShaderModule( SpvReflectShaderModule* p_module ); +/*! @fn spvReflectCreateShaderModule2 + + @param flags Flags for module creations. + @param size Size in bytes of SPIR-V code. + @param p_code Pointer to SPIR-V code. + @param p_module Pointer to an instance of SpvReflectShaderModule. + @return SPV_REFLECT_RESULT_SUCCESS on success. + +*/ +SpvReflectResult spvReflectCreateShaderModule2( + SpvReflectModuleFlags flags, + size_t size, + const void* p_code, + SpvReflectShaderModule* p_module +); + SPV_REFLECT_DEPRECATED("renamed to spvReflectCreateShaderModule") SpvReflectResult spvReflectGetShaderModule( size_t size, @@ -1329,7 +1437,7 @@ SpvReflectResult spvReflectChangeInputVariableLocation( by multiple entry points in the module, it will be changed in all of them. @param p_module Pointer to an instance of SpvReflectShaderModule. - @param p_output_variable Pointer to the output variable to update. + @param p_output_variable Pointer to the output variable to update. @param new_location The new location to assign to p_output_variable. @return If successful, returns SPV_REFLECT_RESULT_SUCCESS. Otherwise, the error code indicates the cause of @@ -1351,11 +1459,21 @@ SpvReflectResult spvReflectChangeOutputVariableLocation( */ const char* spvReflectSourceLanguage(SpvSourceLanguage source_lang); +/*! @fn spvReflectBlockVariableTypeName + + @param p_var Pointer to block variable. + @return Returns string of block variable's type description type name + or NULL if p_var is NULL. +*/ +const char* spvReflectBlockVariableTypeName( + const SpvReflectBlockVariable* p_var +); + #if defined(__cplusplus) }; #endif -#if defined(__cplusplus) +#if defined(__cplusplus) && !defined(SPIRV_REFLECT_DISABLE_CPP_BINDINGS) #include #include #include @@ -1368,11 +1486,14 @@ namespace spv_reflect { class ShaderModule { public: ShaderModule(); - ShaderModule(size_t size, const void* p_code); - ShaderModule(const std::vector& code); - ShaderModule(const std::vector& code); + ShaderModule(size_t size, const void* p_code, SpvReflectModuleFlags flags = SPV_REFLECT_MODULE_FLAG_NONE); + ShaderModule(const std::vector& code, SpvReflectModuleFlags flags = SPV_REFLECT_MODULE_FLAG_NONE); + ShaderModule(const std::vector& code, SpvReflectModuleFlags flags = SPV_REFLECT_MODULE_FLAG_NONE); ~ShaderModule(); + ShaderModule(ShaderModule&& other); + ShaderModule& operator=(ShaderModule&& other); + SpvReflectResult GetResult() const; const SpvReflectShaderModule& GetShaderModule() const; @@ -1477,8 +1598,9 @@ inline ShaderModule::ShaderModule() {} @param p_code */ -inline ShaderModule::ShaderModule(size_t size, const void* p_code) { - m_result = spvReflectCreateShaderModule( +inline ShaderModule::ShaderModule(size_t size, const void* p_code, SpvReflectModuleFlags flags) { + m_result = spvReflectCreateShaderModule2( + flags, size, p_code, &m_module); @@ -1487,10 +1609,11 @@ inline ShaderModule::ShaderModule(size_t size, const void* p_code) { /*! @fn ShaderModule @param code - + */ -inline ShaderModule::ShaderModule(const std::vector& code) { - m_result = spvReflectCreateShaderModule( +inline ShaderModule::ShaderModule(const std::vector& code, SpvReflectModuleFlags flags) { + m_result = spvReflectCreateShaderModule2( + flags, code.size(), code.data(), &m_module); @@ -1499,10 +1622,11 @@ inline ShaderModule::ShaderModule(const std::vector& code) { /*! @fn ShaderModule @param code - + */ -inline ShaderModule::ShaderModule(const std::vector& code) { - m_result = spvReflectCreateShaderModule( +inline ShaderModule::ShaderModule(const std::vector& code, SpvReflectModuleFlags flags) { + m_result = spvReflectCreateShaderModule2( + flags, code.size() * sizeof(uint32_t), code.data(), &m_module); @@ -1516,6 +1640,20 @@ inline ShaderModule::~ShaderModule() { } +inline ShaderModule::ShaderModule(ShaderModule&& other) +{ + *this = std::move(other); +} + +inline ShaderModule& ShaderModule::operator=(ShaderModule&& other) +{ + m_result = std::move(other.m_result); + m_module = std::move(other.m_module); + + other.m_module = {}; + return *this; +} + /*! @fn GetResult @return @@ -2187,5 +2325,5 @@ inline SpvReflectResult ShaderModule::ChangeOutputVariableLocation( } } // namespace spv_reflect -#endif // defined(__cplusplus) +#endif // defined(__cplusplus) && !defined(SPIRV_REFLECT_DISABLE_CPP_WRAPPER) #endif // SPIRV_REFLECT_H diff --git a/WickedEngine/shaders/ShaderInterop_EmittedParticle.h b/WickedEngine/shaders/ShaderInterop_EmittedParticle.h index 58e2a21a1..782e2321b 100644 --- a/WickedEngine/shaders/ShaderInterop_EmittedParticle.h +++ b/WickedEngine/shaders/ShaderInterop_EmittedParticle.h @@ -44,8 +44,8 @@ CBUFFER(EmittedParticleCB, CBSLOT_OTHER_EMITTEDPARTICLE) uint xEmitCount; uint xEmitterMeshIndexCount; - uint xEmitterMeshVertexPositionStride; float xEmitterRandomness; + float xParticleRandomColorFactor; float xParticleSize; float xParticleScaling; @@ -90,11 +90,6 @@ CBUFFER(EmittedParticleCB, CBSLOT_OTHER_EMITTEDPARTICLE) float3 xParticleVelocity; float xParticleDrag; - - float xParticleRandomColorFactor; - int padding0; - int padding1; - int padding2; }; static const uint THREADCOUNT_EMIT = 256; diff --git a/WickedEngine/shaders/bvh_primitivesCS.hlsl b/WickedEngine/shaders/bvh_primitivesCS.hlsl index bcf0a8a1f..460389059 100644 --- a/WickedEngine/shaders/bvh_primitivesCS.hlsl +++ b/WickedEngine/shaders/bvh_primitivesCS.hlsl @@ -28,16 +28,13 @@ void main(uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex) ShaderMaterial material = load_material(geometry.materialIndex); uint startIndex = prim.primitiveIndex * 3 + geometry.indexOffset; - uint i0 = bindless_ib[geometry.ib][startIndex + 0]; - uint i1 = bindless_ib[geometry.ib][startIndex + 1]; - uint i2 = bindless_ib[geometry.ib][startIndex + 2]; - - uint4 data0 = bindless_buffers[geometry.vb_pos_nor_wind].Load4(i0 * 16); - uint4 data1 = bindless_buffers[geometry.vb_pos_nor_wind].Load4(i1 * 16); - uint4 data2 = bindless_buffers[geometry.vb_pos_nor_wind].Load4(i2 * 16); - float3 p0 = asfloat(data0.xyz); - float3 p1 = asfloat(data1.xyz); - float3 p2 = asfloat(data2.xyz); + uint i0 = bindless_buffers_uint[geometry.ib][startIndex + 0]; + uint i1 = bindless_buffers_uint[geometry.ib][startIndex + 1]; + uint i2 = bindless_buffers_uint[geometry.ib][startIndex + 2]; + + float3 p0 = bindless_buffers_float4[geometry.vb_pos_nor_wind][i0].xyz; + float3 p1 = bindless_buffers_float4[geometry.vb_pos_nor_wind][i1].xyz; + float3 p2 = bindless_buffers_float4[geometry.vb_pos_nor_wind][i2].xyz; float3 P0 = mul(inst.transform.GetMatrix(), float4(p0, 1)).xyz; float3 P1 = mul(inst.transform.GetMatrix(), float4(p1, 1)).xyz; float3 P2 = mul(inst.transform.GetMatrix(), float4(p2, 1)).xyz; diff --git a/WickedEngine/shaders/emittedparticleHF.hlsli b/WickedEngine/shaders/emittedparticleHF.hlsli index 86bbc084e..29c48e55f 100644 --- a/WickedEngine/shaders/emittedparticleHF.hlsli +++ b/WickedEngine/shaders/emittedparticleHF.hlsli @@ -18,13 +18,13 @@ ShaderMaterial EmitterGetMaterial() struct VertextoPixel { - float4 pos : SV_POSITION; - float4 tex : TEXCOORD0; - nointerpolation float size : TEXCOORD1; - nointerpolation uint color : TEXCOORD2; + float4 pos : SV_POSITION; + float4 tex : TEXCOORD0; float3 P : WORLDPOSITION; - nointerpolation float frameBlend : FRAMEBLEND; float2 unrotated_uv : UNROTATED_UV; + nointerpolation float frameBlend : FRAMEBLEND; + nointerpolation float size : PARTICLESIZE; + nointerpolation uint color : PARTICLECOLOR; }; #endif // WI_EMITTEDPARTICLE_HF diff --git a/WickedEngine/shaders/emittedparticleMS.hlsl b/WickedEngine/shaders/emittedparticleMS.hlsl index e1a8d3f7f..168e1b674 100644 --- a/WickedEngine/shaders/emittedparticleMS.hlsl +++ b/WickedEngine/shaders/emittedparticleMS.hlsl @@ -18,13 +18,29 @@ StructuredBuffer culledIndirectionBuffer2 : register(t3); static const uint VERTEXCOUNT = THREADCOUNT_MESH_SHADER * BILLBOARD_VERTEXCOUNT; static const uint PRIMITIVECOUNT = THREADCOUNT_MESH_SHADER * 2; +// VertexToPixel separated into two structures: +struct VertextoPixel_MS +{ + float4 pos : SV_POSITION; + float4 tex : TEXCOORD0; + float3 P : WORLDPOSITION; + float2 unrotated_uv : UNROTATED_UV; +}; +struct VertextoPixel_MS_PRIM +{ + nointerpolation float frameBlend : FRAMEBLEND; + nointerpolation float size : PARTICLESIZE; + nointerpolation uint color : PARTICLECOLOR; +}; + [outputtopology("triangle")] [numthreads(THREADCOUNT_MESH_SHADER, 1, 1)] void main( in uint tid : SV_DispatchThreadID, in uint tig : SV_GroupIndex, in uint gid : SV_GroupID, - out vertices VertextoPixel verts[VERTEXCOUNT], + out vertices VertextoPixel_MS verts[VERTEXCOUNT], + out primitives VertextoPixel_MS_PRIM sharedPrimitives[PRIMITIVECOUNT], out indices uint3 triangles[PRIMITIVECOUNT]) { uint particleCount = counterBuffer.Load(PARTICLECOUNTER_OFFSET_CULLEDCOUNT); @@ -35,14 +51,8 @@ void main( if (tig >= realGroupCount) return; - -#ifdef SPIRV - // Workaround for mesh shader compile issue with vulkan: https://github.com/microsoft/DirectXShaderCompiler/issues/4865#issuecomment-1346806816 - ShaderGeometry geometry; - geometry.init(); // obviously, this will not produce correct result, but let the shader compile at least in vulkan -#else + ShaderGeometry geometry = EmitterGetGeometry(); -#endif // SPIRV uint instanceID = tid; uint particleIndex = culledIndirectionBuffer2[culledIndirectionBuffer[instanceID]]; @@ -59,30 +69,32 @@ void main( lerp(xEmitterFrameStart, xEmitterFrameCount, lifeLerp) : ((xEmitterFrameStart + particle.life * xEmitterFrameRate) % xEmitterFrameCount); const float frameBlend = frac(spriteframe); - + // Transform the vertices and write them for (uint i = 0; i < BILLBOARD_VERTEXCOUNT; ++i) { uint vertexID = particleIndex * 4 + i; - uint4 data = bindless_buffers[geometry.vb_pos_nor_wind].Load4(vertexID * 16); - float3 position = asfloat(data.xyz); - float3 normal = normalize(unpack_unitvector(data.w)); - float4 uvsets = unpack_half4(bindless_buffers[geometry.vb_uvs].Load2(vertexID * 8)); - uint color = bindless_buffers[geometry.vb_col].Load(vertexID * 4); + float4 pos_nor_wind = bindless_buffers_float4[geometry.vb_pos_nor_wind][vertexID]; + float3 position = pos_nor_wind.xyz; + float3 normal = normalize(unpack_unitvector(asuint(pos_nor_wind.w))); + float4 uvsets = bindless_buffers_float4[geometry.vb_uvs][vertexID]; - VertextoPixel Out; + VertextoPixel_MS Out; Out.P = position; Out.pos = mul(GetCamera().view_projection, float4(position, 1)); - Out.tex = uvsets; - Out.size = size; - Out.color = color; Out.unrotated_uv = BILLBOARD[i].xy * float2(1, -1) * 0.5f + 0.5f; - Out.frameBlend = frameBlend; verts[tig * BILLBOARD_VERTEXCOUNT + i] = Out; } + VertextoPixel_MS_PRIM OutQuad; + OutQuad.color = pack_rgba(bindless_buffers_float4[geometry.vb_col][particleIndex * 4]); + OutQuad.size = size; + OutQuad.frameBlend = frameBlend; + sharedPrimitives[tig * 2 + 0] = OutQuad; + sharedPrimitives[tig * 2 + 1] = OutQuad; + triangles[tig * 2 + 0] = uint3(0, 1, 2) + tig * BILLBOARD_VERTEXCOUNT; triangles[tig * 2 + 1] = uint3(2, 1, 3) + tig * BILLBOARD_VERTEXCOUNT; } diff --git a/WickedEngine/shaders/emittedparticleVS.hlsl b/WickedEngine/shaders/emittedparticleVS.hlsl index c32e0d870..6c3a46ebe 100644 --- a/WickedEngine/shaders/emittedparticleVS.hlsl +++ b/WickedEngine/shaders/emittedparticleVS.hlsl @@ -20,11 +20,11 @@ VertextoPixel main(uint vid : SV_VertexID, uint instanceID : SV_InstanceID) uint particleIndex = culledIndirectionBuffer2[culledIndirectionBuffer[instanceID]]; uint vertexID = particleIndex * 4 + vid; - uint4 data = bindless_buffers[geometry.vb_pos_nor_wind].Load4(vertexID * 16); - float3 position = asfloat(data.xyz); - float3 normal = normalize(unpack_unitvector(data.w)); - float4 uvsets = unpack_half4(bindless_buffers[geometry.vb_uvs].Load2(vertexID * 8)); - uint color = bindless_buffers[geometry.vb_col].Load(vertexID * 4); + float4 pos_nor_wind = bindless_buffers_float4[geometry.vb_pos_nor_wind][vertexID]; + float3 position = pos_nor_wind.xyz; + float3 normal = normalize(unpack_unitvector(asuint(pos_nor_wind.w))); + float4 uvsets = bindless_buffers_float4[geometry.vb_uvs][vertexID]; + float4 color = bindless_buffers_float4[geometry.vb_col][vertexID]; // load particle data: @@ -45,7 +45,7 @@ VertextoPixel main(uint vid : SV_VertexID, uint instanceID : SV_InstanceID) Out.pos = mul(GetCamera().view_projection, float4(position, 1)); Out.tex = uvsets; Out.size = size; - Out.color = color; + Out.color = pack_rgba(color); Out.unrotated_uv = BILLBOARD[vertexID % 4].xy * float2(1, -1) * 0.5f + 0.5f; Out.frameBlend = frameBlend; return Out; diff --git a/WickedEngine/shaders/emittedparticle_emitCS.hlsl b/WickedEngine/shaders/emittedparticle_emitCS.hlsl index 437fc6013..05680feeb 100644 --- a/WickedEngine/shaders/emittedparticle_emitCS.hlsl +++ b/WickedEngine/shaders/emittedparticle_emitCS.hlsl @@ -10,7 +10,7 @@ RWByteAddressBuffer counterBuffer : register(u4); #ifdef EMIT_FROM_MESH Buffer meshIndexBuffer : register(t0); -ByteAddressBuffer meshVertexBuffer_POS : register(t1); +Buffer meshVertexBuffer_POS : register(t1); #endif // EMIT_FROM_MESH @@ -18,114 +18,96 @@ ByteAddressBuffer meshVertexBuffer_POS : register(t1); void main(uint3 DTid : SV_DispatchThreadID) { uint emitCount = counterBuffer.Load(PARTICLECOUNTER_OFFSET_REALEMITCOUNT); + if (DTid.x >= emitCount) + return; + + RNG rng; + rng.init(uint2(xEmitterRandomness, DTid.x), GetFrame().frame_count); - if(DTid.x < emitCount) - { - RNG rng; - rng.init(uint2(xEmitterRandomness, DTid.x), GetFrame().frame_count); - - const float4x4 worldMatrix = xEmitterTransform.GetMatrix(); + const float4x4 worldMatrix = xEmitterTransform.GetMatrix(); #ifdef EMIT_FROM_MESH - // random triangle on emitter surface: - uint tri = (uint)((xEmitterMeshIndexCount / 3) * hash1(DTid.x + GetFrame().frame_count)); + // random triangle on emitter surface: + const uint triangleCount = xEmitterMeshIndexCount / 3; + const uint tri = rng.next_uint(triangleCount); - // load indices of triangle from index buffer - uint i0 = meshIndexBuffer[tri * 3 + 0]; - uint i1 = meshIndexBuffer[tri * 3 + 1]; - uint i2 = meshIndexBuffer[tri * 3 + 2]; + // load indices of triangle from index buffer + uint i0 = meshIndexBuffer[tri * 3 + 0]; + uint i1 = meshIndexBuffer[tri * 3 + 1]; + uint i2 = meshIndexBuffer[tri * 3 + 2]; - // load vertices of triangle from vertex buffer: - float4 pos_nor0 = asfloat(meshVertexBuffer_POS.Load4(i0 * xEmitterMeshVertexPositionStride)); - float4 pos_nor1 = asfloat(meshVertexBuffer_POS.Load4(i1 * xEmitterMeshVertexPositionStride)); - float4 pos_nor2 = asfloat(meshVertexBuffer_POS.Load4(i2 * xEmitterMeshVertexPositionStride)); + // load vertices of triangle from vertex buffer: + float4 pos_nor0 = meshVertexBuffer_POS[i0]; + float4 pos_nor1 = meshVertexBuffer_POS[i1]; + float4 pos_nor2 = meshVertexBuffer_POS[i2]; + + float3 nor0 = unpack_unitvector(asuint(pos_nor0.w)); + float3 nor1 = unpack_unitvector(asuint(pos_nor1.w)); + float3 nor2 = unpack_unitvector(asuint(pos_nor2.w)); - uint nor_u = asuint(pos_nor0.w); - float3 nor0; - { - nor0.x = (float)((nor_u >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - nor0.y = (float)((nor_u >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - nor0.z = (float)((nor_u >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - } - nor_u = asuint(pos_nor1.w); - float3 nor1; - { - nor1.x = (float)((nor_u >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - nor1.y = (float)((nor_u >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - nor1.z = (float)((nor_u >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - } - nor_u = asuint(pos_nor2.w); - float3 nor2; - { - nor2.x = (float)((nor_u >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - nor2.y = (float)((nor_u >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - nor2.z = (float)((nor_u >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - } + // random barycentric coords: + float f = rng.next_float(); + float g = rng.next_float(); + [flatten] + if (f + g > 1) + { + f = 1 - f; + g = 1 - g; + } + float2 bary = float2(f, g); - // random barycentric coords: - float f = rng.next_float(); - float g = rng.next_float(); - [flatten] - if (f + g > 1) - { - f = 1 - f; - g = 1 - g; - } - - // compute final surface position on triangle from barycentric coords: - float3 pos = pos_nor0.xyz + f * (pos_nor1.xyz - pos_nor0.xyz) + g * (pos_nor2.xyz - pos_nor0.xyz); - float3 nor = nor0 + f * (nor1 - nor0) + g * (nor2 - nor0); - pos = mul(worldMatrix, float4(pos, 1)).xyz; - nor = normalize(mul((float3x3)worldMatrix, nor)); + // compute final surface position on triangle from barycentric coords: + float3 pos = attribute_at_bary(pos_nor0.xyz, pos_nor1.xyz, pos_nor2.xyz, bary); + float3 nor = normalize(attribute_at_bary(nor0, nor1, nor2, bary)); + pos = mul(worldMatrix, float4(pos, 1)).xyz; + nor = normalize(mul((float3x3)worldMatrix, nor)); #else #ifdef EMITTER_VOLUME - // Emit inside volume: - float3 pos = mul(worldMatrix, float4(rng.next_float() * 2 - 1, rng.next_float() * 2 - 1, rng.next_float() * 2 - 1, 1)).xyz; + // Emit inside volume: + float3 pos = mul(worldMatrix, float4(rng.next_float() * 2 - 1, rng.next_float() * 2 - 1, rng.next_float() * 2 - 1, 1)).xyz; #else - // Just emit from center point: - float3 pos = mul(worldMatrix, float4(0, 0, 0, 1)).xyz; + // Just emit from center point: + float3 pos = mul(worldMatrix, float4(0, 0, 0, 1)).xyz; #endif // EMITTER_VOLUME - float3 nor = 0; + float3 nor = 0; #endif // EMIT_FROM_MESH - float particleStartingSize = xParticleSize + xParticleSize * (rng.next_float() - 0.5f) * xParticleRandomFactor; + float particleStartingSize = xParticleSize + xParticleSize * (rng.next_float() - 0.5f) * xParticleRandomFactor; - // create new particle: - Particle particle; - particle.position = pos; - particle.force = 0; - particle.mass = xParticleMass; - particle.velocity = xParticleVelocity + (nor + (float3(rng.next_float(), rng.next_float(), rng.next_float()) - 0.5f) * xParticleRandomFactor) * xParticleNormalFactor; - particle.rotationalVelocity = xParticleRotation + (rng.next_float() - 0.5f) * xParticleRandomFactor; - particle.maxLife = xParticleLifeSpan + xParticleLifeSpan * (rng.next_float() - 0.5f) * xParticleLifeSpanRandomness; - particle.life = particle.maxLife; - particle.sizeBeginEnd = float2(particleStartingSize, particleStartingSize * xParticleScaling); - particle.color_mirror = 0; - particle.color_mirror |= ((rng.next_float() > 0.5f) << 31) & 0x10000000; - particle.color_mirror |= ((rng.next_float() < 0.5f) << 30) & 0x20000000; + // create new particle: + Particle particle; + particle.position = pos; + particle.force = 0; + particle.mass = xParticleMass; + particle.velocity = xParticleVelocity + (nor + (float3(rng.next_float(), rng.next_float(), rng.next_float()) - 0.5f) * xParticleRandomFactor) * xParticleNormalFactor; + particle.rotationalVelocity = xParticleRotation + (rng.next_float() - 0.5f) * xParticleRandomFactor; + particle.maxLife = xParticleLifeSpan + xParticleLifeSpan * (rng.next_float() - 0.5f) * xParticleLifeSpanRandomness; + particle.life = particle.maxLife; + particle.sizeBeginEnd = float2(particleStartingSize, particleStartingSize * xParticleScaling); + particle.color_mirror = 0; + particle.color_mirror |= ((rng.next_float() > 0.5f) << 31) & 0x10000000; + particle.color_mirror |= ((rng.next_float() < 0.5f) << 30) & 0x20000000; - uint color_modifier = 0; - color_modifier |= (uint)(255.0 * lerp(1, rng.next_float(), xParticleRandomColorFactor)) << 0; - color_modifier |= (uint)(255.0 * lerp(1, rng.next_float(), xParticleRandomColorFactor)) << 8; - color_modifier |= (uint)(255.0 * lerp(1, rng.next_float(), xParticleRandomColorFactor)) << 16; - particle.color_mirror |= pack_rgba(float4(EmitterGetMaterial().baseColor.rgb, 1)) & color_modifier; + uint color_modifier = 0; + color_modifier |= (uint) (255.0 * lerp(1, rng.next_float(), xParticleRandomColorFactor)) << 0; + color_modifier |= (uint) (255.0 * lerp(1, rng.next_float(), xParticleRandomColorFactor)) << 8; + color_modifier |= (uint) (255.0 * lerp(1, rng.next_float(), xParticleRandomColorFactor)) << 16; + particle.color_mirror |= pack_rgba(float4(EmitterGetMaterial().baseColor.rgb, 1)) & color_modifier; + + // new particle index retrieved from dead list (pop): + uint deadCount; + counterBuffer.InterlockedAdd(PARTICLECOUNTER_OFFSET_DEADCOUNT, -1, deadCount); + uint newParticleIndex = deadBuffer[deadCount - 1]; + // write out the new particle: + particleBuffer[newParticleIndex] = particle; - // new particle index retrieved from dead list (pop): - uint deadCount; - counterBuffer.InterlockedAdd(PARTICLECOUNTER_OFFSET_DEADCOUNT, -1, deadCount); - uint newParticleIndex = deadBuffer[deadCount - 1]; - - // write out the new particle: - particleBuffer[newParticleIndex] = particle; - - // and add index to the alive list (push): - uint aliveCount; - counterBuffer.InterlockedAdd(PARTICLECOUNTER_OFFSET_ALIVECOUNT, 1, aliveCount); - aliveBuffer_CURRENT[aliveCount] = newParticleIndex; - } + // and add index to the alive list (push): + uint aliveCount; + counterBuffer.InterlockedAdd(PARTICLECOUNTER_OFFSET_ALIVECOUNT, 1, aliveCount); + aliveBuffer_CURRENT[aliveCount] = newParticleIndex; } diff --git a/WickedEngine/shaders/emittedparticle_simulateCS.hlsl b/WickedEngine/shaders/emittedparticle_simulateCS.hlsl index 78199f83f..f4b60192b 100644 --- a/WickedEngine/shaders/emittedparticle_simulateCS.hlsl +++ b/WickedEngine/shaders/emittedparticle_simulateCS.hlsl @@ -15,9 +15,9 @@ RWStructuredBuffer aliveBuffer_NEW : register(u2); RWStructuredBuffer deadBuffer : register(u3); RWByteAddressBuffer counterBuffer : register(u4); RWStructuredBuffer distanceBuffer : register(u6); -RWByteAddressBuffer vertexBuffer_POS : register(u7); -RWByteAddressBuffer vertexBuffer_UVS : register(u8); -RWByteAddressBuffer vertexBuffer_COL : register(u9); +RWBuffer vertexBuffer_POS : register(u7); +RWBuffer vertexBuffer_UVS : register(u8); +RWBuffer vertexBuffer_COL : register(u9); RWStructuredBuffer culledIndirectionBuffer : register(u10); RWStructuredBuffer culledIndirectionBuffer2 : register(u11); @@ -292,12 +292,9 @@ void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex) quadPos = mul(quadPos, (float3x3)GetCamera().view); // reversed mul for inverse camera rotation! // write out vertex: - uint4 data; - data.xyz = asuint(particle.position + quadPos); - data.w = pack_unitvector(normalize(-GetCamera().forward)); - vertexBuffer_POS.Store4((v0 + vertexID) * 16, data); - vertexBuffer_UVS.Store2((v0 + vertexID) * 8, pack_half4(float4(uv, uv2))); - vertexBuffer_COL.Store((v0 + vertexID) * 4, particleColorPacked); + vertexBuffer_POS[v0 + vertexID] = float4(particle.position + quadPos, asfloat(pack_unitvector(normalize(-GetCamera().forward)))); + vertexBuffer_UVS[v0 + vertexID] = float4(uv, uv2); + vertexBuffer_COL[v0 + vertexID] = unpack_rgba(particleColorPacked); } // Frustum culling: @@ -329,10 +326,10 @@ void main(uint3 DTid : SV_DispatchThreadID, uint Gid : SV_GroupIndex) counterBuffer.InterlockedAdd(PARTICLECOUNTER_OFFSET_DEADCOUNT, 1, deadIndex); deadBuffer[deadIndex] = particleIndex; - vertexBuffer_POS.Store4((v0 + 0) * 16, 0); - vertexBuffer_POS.Store4((v0 + 1) * 16, 0); - vertexBuffer_POS.Store4((v0 + 2) * 16, 0); - vertexBuffer_POS.Store4((v0 + 3) * 16, 0); + vertexBuffer_POS[v0 + 0] = 0; + vertexBuffer_POS[v0 + 1] = 0; + vertexBuffer_POS[v0 + 2] = 0; + vertexBuffer_POS[v0 + 3] = 0; } } diff --git a/WickedEngine/shaders/globals.hlsli b/WickedEngine/shaders/globals.hlsli index 035f5636d..4281fddf5 100644 --- a/WickedEngine/shaders/globals.hlsli +++ b/WickedEngine/shaders/globals.hlsli @@ -39,11 +39,30 @@ "SRV(t0, space = 11, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ "SRV(t0, space = 12, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ "SRV(t0, space = 13, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ - "UAV(u0, space = 14, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ - "UAV(u0, space = 15, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ - "UAV(u0, space = 16, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ - "UAV(u0, space = 17, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ - "UAV(u0, space = 18, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)" \ + "SRV(t0, space = 14, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "SRV(t0, space = 15, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "SRV(t0, space = 16, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "SRV(t0, space = 17, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "SRV(t0, space = 18, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "SRV(t0, space = 19, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "SRV(t0, space = 20, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "UAV(u0, space = 21, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "UAV(u0, space = 22, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "UAV(u0, space = 23, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "UAV(u0, space = 24, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "UAV(u0, space = 25, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "UAV(u0, space = 26, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "UAV(u0, space = 27, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "UAV(u0, space = 28, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "UAV(u0, space = 29, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "UAV(u0, space = 30, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "UAV(u0, space = 31, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "UAV(u0, space = 32, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "UAV(u0, space = 33, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "SRV(t0, space = 34, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "SRV(t0, space = 35, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "SRV(t0, space = 36, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," \ + "SRV(t0, space = 37, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)" \ "), " \ "StaticSampler(s100, addressU = TEXTURE_ADDRESS_CLAMP, addressV = TEXTURE_ADDRESS_CLAMP, addressW = TEXTURE_ADDRESS_CLAMP, filter = FILTER_MIN_MAG_MIP_LINEAR)," \ "StaticSampler(s101, addressU = TEXTURE_ADDRESS_WRAP, addressV = TEXTURE_ADDRESS_WRAP, addressW = TEXTURE_ADDRESS_WRAP, filter = FILTER_MIN_MAG_MIP_LINEAR)," \ @@ -80,10 +99,18 @@ static const uint DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER = 2; static const uint DESCRIPTOR_SET_BINDLESS_SAMPLER = 3; static const uint DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE = 4; static const uint DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE = 5; -static const uint DESCRIPTOR_SET_BINDLESS_ACCELERATION_STRUCTURE = 6; +static const uint DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER = 6; +static const uint DESCRIPTOR_SET_BINDLESS_ACCELERATION_STRUCTURE = 7; [[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] ByteAddressBuffer bindless_buffers[]; -[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer bindless_ib[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer bindless_buffers_uint[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer bindless_buffers_uint2[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer bindless_buffers_uint3[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer bindless_buffers_uint4[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer bindless_buffers_float[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer bindless_buffers_float2[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer bindless_buffers_float3[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer bindless_buffers_float4[]; [[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLER)]] SamplerState bindless_samplers[]; [[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE)]] Texture2D bindless_textures[]; [[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE)]] Texture2DArray bindless_textures2DArray[]; @@ -96,6 +123,14 @@ static const uint DESCRIPTOR_SET_BINDLESS_ACCELERATION_STRUCTURE = 6; [[vk::binding(0, DESCRIPTOR_SET_BINDLESS_SAMPLED_IMAGE)]] Texture2D bindless_textures_uint4[]; [[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] RWByteAddressBuffer bindless_rwbuffers[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer bindless_rwbuffers_uint[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer bindless_rwbuffers_uint2[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer bindless_rwbuffers_uint3[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer bindless_rwbuffers_uint4[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer bindless_rwbuffers_float[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer bindless_rwbuffers_float2[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer bindless_rwbuffers_float3[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer bindless_rwbuffers_float4[]; [[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE)]] RWTexture2D bindless_rwtextures[]; [[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE)]] RWTexture2DArray bindless_rwtextures2DArray[]; [[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE)]] RWTexture3D bindless_rwtextures3D[]; @@ -108,28 +143,56 @@ static const uint DESCRIPTOR_SET_BINDLESS_ACCELERATION_STRUCTURE = 6; SamplerState bindless_samplers[] : register(space1); Texture2D bindless_textures[] : register(space2); ByteAddressBuffer bindless_buffers[] : register(space3); -Buffer bindless_ib[] : register(space4); +Buffer bindless_buffers_uint[] : register(space4); +Buffer bindless_buffers_uint2[] : register(space5); +Buffer bindless_buffers_uint3[] : register(space6); +Buffer bindless_buffers_uint4[] : register(space7); +Buffer bindless_buffers_float[] : register(space8); +Buffer bindless_buffers_float2[] : register(space9); +Buffer bindless_buffers_float3[] : register(space10); +Buffer bindless_buffers_float4[] : register(space11); #ifdef RTAPI -RaytracingAccelerationStructure bindless_accelerationstructures[] : register(space5); +RaytracingAccelerationStructure bindless_accelerationstructures[] : register(space12); #endif // RTAPI -Texture2DArray bindless_textures2DArray[] : register(space6); -TextureCube bindless_cubemaps[] : register(space7); -TextureCubeArray bindless_cubearrays[] : register(space8); -Texture3D bindless_textures3D[] : register(space9); -Texture2D bindless_textures_float[] : register(space10); -Texture2D bindless_textures_float2[] : register(space11); -Texture2D bindless_textures_uint[] : register(space12); -Texture2D bindless_textures_uint4[] : register(space13); +Texture2DArray bindless_textures2DArray[] : register(space13); +TextureCube bindless_cubemaps[] : register(space14); +TextureCubeArray bindless_cubearrays[] : register(space15); +Texture3D bindless_textures3D[] : register(space16); +Texture2D bindless_textures_float[] : register(space17); +Texture2D bindless_textures_float2[] : register(space18); +Texture2D bindless_textures_uint[] : register(space19); +Texture2D bindless_textures_uint4[] : register(space20); + +RWTexture2D bindless_rwtextures[] : register(space21); +RWByteAddressBuffer bindless_rwbuffers[] : register(space22); +RWBuffer bindless_rwbuffers_uint[] : register(space23); +RWBuffer bindless_rwbuffers_uint2[] : register(space24); +RWBuffer bindless_rwbuffers_uint3[] : register(space25); +RWBuffer bindless_rwbuffers_uint4[] : register(space26); +RWBuffer bindless_rwbuffers_float[] : register(space27); +RWBuffer bindless_rwbuffers_float2[] : register(space28); +RWBuffer bindless_rwbuffers_float3[] : register(space29); +RWBuffer bindless_rwbuffers_float4[] : register(space30); +RWTexture2DArray bindless_rwtextures2DArray[] : register(space31); +RWTexture3D bindless_rwtextures3D[] : register(space32); +RWTexture2D bindless_rwtextures_uint[] : register(space33); -RWTexture2D bindless_rwtextures[] : register(space14); -RWByteAddressBuffer bindless_rwbuffers[] : register(space15); -RWTexture2DArray bindless_rwtextures2DArray[] : register(space16); -RWTexture3D bindless_rwtextures3D[] : register(space17); -RWTexture2D bindless_rwtextures_uint[] : register(space18); #endif // SPIRV #include "ShaderInterop_Renderer.h" +#ifdef SPIRV +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] StructuredBuffer bindless_buffers_meshinstance[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] StructuredBuffer bindless_buffers_geometry[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] StructuredBuffer bindless_buffers_meshlet[]; +[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] StructuredBuffer bindless_buffers_material[]; +#else +StructuredBuffer bindless_buffers_meshinstance[] : register(space34); +StructuredBuffer bindless_buffers_geometry[] : register(space35); +StructuredBuffer bindless_buffers_meshlet[] : register(space36); +StructuredBuffer bindless_buffers_material[] : register(space37); +#endif // SPIRV + inline FrameCB GetFrame() { return g_xFrame; @@ -148,19 +211,19 @@ inline ShaderWeather GetWeather() } inline ShaderMeshInstance load_instance(uint instanceIndex) { - return bindless_buffers[GetScene().instancebuffer].Load(instanceIndex * sizeof(ShaderMeshInstance)); + return bindless_buffers_meshinstance[GetScene().instancebuffer][instanceIndex]; } inline ShaderGeometry load_geometry(uint geometryIndex) { - return bindless_buffers[GetScene().geometrybuffer].Load(geometryIndex * sizeof(ShaderGeometry)); + return bindless_buffers_geometry[GetScene().geometrybuffer][geometryIndex]; } inline ShaderMeshlet load_meshlet(uint meshletIndex) { - return bindless_buffers[GetScene().meshletbuffer].Load(meshletIndex * sizeof(ShaderMeshlet)); + return bindless_buffers_meshlet[GetScene().meshletbuffer][meshletIndex]; } inline ShaderMaterial load_material(uint materialIndex) { - return bindless_buffers[GetScene().materialbuffer].Load(materialIndex * sizeof(ShaderMaterial)); + return bindless_buffers_material[GetScene().materialbuffer][materialIndex]; } uint load_entitytile(uint tileIndex) { diff --git a/WickedEngine/shaders/hairparticleVS.hlsl b/WickedEngine/shaders/hairparticleVS.hlsl index 4c51aa701..591671eb3 100644 --- a/WickedEngine/shaders/hairparticleVS.hlsl +++ b/WickedEngine/shaders/hairparticleVS.hlsl @@ -12,10 +12,10 @@ VertexToPixel main(uint vid : SV_VERTEXID) Out.primitiveID = vid / 3; uint vertexID = primitiveBuffer[vid]; - uint4 data = bindless_buffers[geometry.vb_pos_nor_wind].Load4(vertexID * 16); - float3 position = asfloat(data.xyz); - float3 normal = normalize(unpack_unitvector(data.w)); - float4 uvsets = unpack_half4(bindless_buffers[geometry.vb_uvs].Load2(vertexID * 8)); + float4 pos_nor_wind = bindless_buffers_float4[geometry.vb_pos_nor_wind][vertexID]; + float3 position = pos_nor_wind.xyz; + float3 normal = normalize(unpack_unitvector(asuint(pos_nor_wind.w))); + float4 uvsets = bindless_buffers_float4[geometry.vb_uvs][vertexID]; Out.fade = saturate(distance(position.xyz, GetCamera().position.xyz) / xHairViewDistance); Out.fade = saturate(Out.fade - 0.8f) * 5.0f; // fade will be on edge and inwards 20% diff --git a/WickedEngine/shaders/hairparticle_simulateCS.hlsl b/WickedEngine/shaders/hairparticle_simulateCS.hlsl index 99911418b..cb3f04167 100644 --- a/WickedEngine/shaders/hairparticle_simulateCS.hlsl +++ b/WickedEngine/shaders/hairparticle_simulateCS.hlsl @@ -10,12 +10,12 @@ static const float3 HAIRPATCH[] = { }; Buffer meshIndexBuffer : register(t0); -ByteAddressBuffer meshVertexBuffer_POS : register(t1); +Buffer meshVertexBuffer_POS : register(t1); Buffer meshVertexBuffer_length : register(t2); RWStructuredBuffer simulationBuffer : register(u0); -RWByteAddressBuffer vertexBuffer_POS : register(u1); -RWByteAddressBuffer vertexBuffer_UVS : register(u2); +RWBuffer vertexBuffer_POS : register(u1); +RWBuffer vertexBuffer_UVS : register(u2); RWBuffer culledIndexBuffer : register(u3); RWStructuredBuffer indirectBuffer : register(u4); @@ -24,11 +24,13 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn { if (DTid.x >= xHairParticleCount) return; - - // Generate patch: - + + RNG rng; + rng.init(uint2(xHairRandomSeed, DTid.x), 0); + // random triangle on emitter surface: - uint tri = (uint)((xHairBaseMeshIndexCount / 3) * hash1(DTid.x)); + const uint triangleCount = xHairBaseMeshIndexCount / 3; + const uint tri = rng.next_uint(triangleCount); // load indices of triangle from index buffer uint i0 = meshIndexBuffer[tri * 3 + 0]; @@ -36,19 +38,17 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn uint i2 = meshIndexBuffer[tri * 3 + 2]; // load vertices of triangle from vertex buffer: - float4 pos_nor0 = asfloat(meshVertexBuffer_POS.Load4(i0 * xHairBaseMeshVertexPositionStride)); - float4 pos_nor1 = asfloat(meshVertexBuffer_POS.Load4(i1 * xHairBaseMeshVertexPositionStride)); - float4 pos_nor2 = asfloat(meshVertexBuffer_POS.Load4(i2 * xHairBaseMeshVertexPositionStride)); - float3 nor0 = unpack_unitvector(asuint(pos_nor0.w)); - float3 nor1 = unpack_unitvector(asuint(pos_nor1.w)); - float3 nor2 = unpack_unitvector(asuint(pos_nor2.w)); + float4 pos_nor0 = meshVertexBuffer_POS[i0]; + float4 pos_nor1 = meshVertexBuffer_POS[i1]; + float4 pos_nor2 = meshVertexBuffer_POS[i2]; + float3 nor0 = unpack_unitvector(asuint(pos_nor0.w)); + float3 nor1 = unpack_unitvector(asuint(pos_nor1.w)); + float3 nor2 = unpack_unitvector(asuint(pos_nor2.w)); float length0 = meshVertexBuffer_length[i0]; float length1 = meshVertexBuffer_length[i1]; float length2 = meshVertexBuffer_length[i2]; // random barycentric coords: - RNG rng; - rng.init(uint2(xHairRandomSeed, DTid.x), 0); float f = rng.next_float(); float g = rng.next_float(); [flatten] @@ -79,12 +79,12 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn binormal_length |= (uint)(lerp(1, rng.next_float(), saturate(xHairRandomness)) * strand_length * 255) << 24; // Identifies the hair strand root particle: - const uint strandID = DTid.x * xHairSegmentCount; - + const uint strandID = DTid.x * xHairSegmentCount; + // Transform particle by the emitter object matrix: const float4x4 worldMatrix = xHairTransform.GetMatrix(); - float3 base = mul(worldMatrix, float4(position.xyz, 1)).xyz; - target = normalize(mul((float3x3)worldMatrix, target)); + float3 base = mul(worldMatrix, float4(position.xyz, 1)).xyz; + target = normalize(mul((float3x3)worldMatrix, target)); const float3 root = base; float3 diff = GetCamera().position - root; @@ -97,7 +97,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn float3 normal = 0; const float delta_time = clamp(GetFrame().delta_time, 0, 1.0 / 30.0); // clamp delta time to avoid simulation blowing up - + for (uint segmentID = 0; segmentID < xHairSegmentCount; ++segmentID) { // Identifies the hair strand segment particle: @@ -111,8 +111,8 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn simulationBuffer[particleID].normal_velocity = f32tof16(target); } - normal += f16tof32(simulationBuffer[particleID].normal_velocity); - normal = normalize(normal); + normal += f16tof32(simulationBuffer[particleID].normal_velocity); + normal = normalize(normal); float len = (binormal_length >> 24) & 0x000000FF; len /= 255.0f; @@ -123,8 +123,8 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn // Accumulate forces, apply colliders: float3 force = 0; - for (uint i = 0; i < GetFrame().forcefieldarray_count; ++i) - { + for (uint i = 0; i < GetFrame().forcefieldarray_count; ++i) + { ShaderEntity entity = load_entity(GetFrame().forcefieldarray_offset + i); [branch] @@ -198,15 +198,15 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn } } } - } + } // Pull back to rest position: - force += (target - normal) * xStiffness; + force += (target - normal) * xStiffness; - force *= delta_time; + force *= delta_time; // Simulation buffer load: - float3 velocity = f16tof32(simulationBuffer[particleID].normal_velocity >> 16u); + float3 velocity = f16tof32(simulationBuffer[particleID].normal_velocity >> 16u); // Apply surface-movement-based velocity: const float3 old_base = simulationBuffer[particleID].position; @@ -272,12 +272,9 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn { position = 0; } - - uint4 data; - data.xyz = asuint(position); - data.w = pack_unitvector(normalize(normal + wind)); - vertexBuffer_POS.Store4((v0 + vertexID) * 16, data); - vertexBuffer_UVS.Store2((v0 + vertexID) * 8, pack_half4(float4(uv, uv))); // a second uv set could be used here + + vertexBuffer_POS[v0 + vertexID] = float4(position, asfloat(pack_unitvector(normalize(normal + wind)))); + vertexBuffer_UVS[v0 + vertexID] = uv.xyxy; // a second uv set could be used here } // Frustum culling: @@ -310,5 +307,5 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint groupIn // Offset next segment root to current tip: base = tip; - } + } } diff --git a/WickedEngine/shaders/impostorVS.hlsl b/WickedEngine/shaders/impostorVS.hlsl index 4dcb35c37..97aba0e30 100644 --- a/WickedEngine/shaders/impostorVS.hlsl +++ b/WickedEngine/shaders/impostorVS.hlsl @@ -8,7 +8,7 @@ static const float2 BILLBOARD[] = { float2(1, 1), }; -ByteAddressBuffer vb_pos_nor : register(t0); +Buffer vb_pos_nor : register(t0); ByteAddressBuffer impostor_data : register(t2); VSOut main(uint vertexID : SV_VertexID) @@ -16,7 +16,7 @@ VSOut main(uint vertexID : SV_VertexID) uint2 data = impostor_data.Load2((vertexID / 4u) * sizeof(uint2)); VSOut Out; - Out.pos3D = asfloat(vb_pos_nor.Load3(vertexID * sizeof(uint4))); + Out.pos3D = vb_pos_nor[vertexID].xyz; Out.pos = mul(GetCamera().view_projection, float4(Out.pos3D, 1)); Out.uv = float2(BILLBOARD[vertexID % 4u] * float2(0.5f, -0.5f) + 0.5f); Out.slice = data.x & 0xFFFFFF; diff --git a/WickedEngine/shaders/impostor_prepareCS.hlsl b/WickedEngine/shaders/impostor_prepareCS.hlsl index 2ba409a17..467659995 100644 --- a/WickedEngine/shaders/impostor_prepareCS.hlsl +++ b/WickedEngine/shaders/impostor_prepareCS.hlsl @@ -11,7 +11,7 @@ static const float3 BILLBOARD[] = }; RWBuffer output_indices : register(u0); -RWByteAddressBuffer output_vertices_pos_nor : register(u1); +RWBuffer output_vertices_pos_nor : register(u1); RWByteAddressBuffer output_impostor_data : register(u2); RWStructuredBuffer output_indirect : register(u3); @@ -103,7 +103,7 @@ void main(uint3 DTid : SV_DispatchThreadID) pos = mul(pos, float3x3(right, up, face)); pos *= instance.radius; pos += instance.center; - output_vertices_pos_nor.Store4((vertexOffset + vertexID) * sizeof(uint4), uint4(asuint(pos), pack_unitvector(face))); + output_vertices_pos_nor[vertexOffset + vertexID] = float4(pos, asfloat(pack_unitvector(face))); } } } diff --git a/WickedEngine/shaders/objectHF.hlsli b/WickedEngine/shaders/objectHF.hlsli index 84cd0a3b3..bf9d55419 100644 --- a/WickedEngine/shaders/objectHF.hlsli +++ b/WickedEngine/shaders/objectHF.hlsli @@ -121,23 +121,9 @@ struct VertexInput uint vertexID : SV_VertexID; uint instanceID : SV_InstanceID; - float4 GetPosition() + float4 GetPositionNormalWind() { - return float4(bindless_buffers[GetMesh().vb_pos_nor_wind].Load(vertexID * sizeof(uint4)), 1); - } - float3 GetNormal() - { - const uint normal_wind = bindless_buffers[GetMesh().vb_pos_nor_wind].Load(vertexID * sizeof(uint4)).w; - float3 normal; - normal.x = (float)((normal_wind >> 0u) & 0xFF) / 255.0 * 2 - 1; - normal.y = (float)((normal_wind >> 8u) & 0xFF) / 255.0 * 2 - 1; - normal.z = (float)((normal_wind >> 16u) & 0xFF) / 255.0 * 2 - 1; - return normal; - } - float GetWindWeight() - { - const uint normal_wind = bindless_buffers[GetMesh().vb_pos_nor_wind].Load(vertexID * sizeof(uint4)).w; - return ((normal_wind >> 24u) & 0xFF) / 255.0; + return bindless_buffers_float4[GetMesh().vb_pos_nor_wind][vertexID]; } float4 GetUVSets() @@ -145,7 +131,7 @@ struct VertexInput [branch] if (GetMesh().vb_uvs < 0) return 0; - return unpack_half4(bindless_buffers[GetMesh().vb_uvs].Load2(vertexID * sizeof(uint2))); + return bindless_buffers_float4[GetMesh().vb_uvs][vertexID]; } ShaderMeshInstancePointer GetInstancePointer() @@ -163,7 +149,7 @@ struct VertexInput [branch] if (GetMesh().vb_atl < 0) return 0; - return unpack_half2(bindless_buffers[GetMesh().vb_atl].Load(vertexID * sizeof(uint))); + return bindless_buffers_float2[GetMesh().vb_atl][vertexID]; } float4 GetVertexColor() @@ -171,7 +157,7 @@ struct VertexInput [branch] if (GetMesh().vb_col < 0) return 1; - return unpack_rgba(bindless_buffers[GetMesh().vb_col].Load(vertexID * sizeof(uint))); + return bindless_buffers_float4[GetMesh().vb_col][vertexID]; } float4 GetTangent() @@ -179,7 +165,7 @@ struct VertexInput [branch] if (GetMesh().vb_tan < 0) return 0; - return unpack_utangent(bindless_buffers[GetMesh().vb_tan].Load(vertexID * sizeof(uint))) * 2 - 1; + return bindless_buffers_float4[GetMesh().vb_tan][vertexID]; } ShaderMeshInstance GetInstance() @@ -206,7 +192,10 @@ struct VertexSurface inline void create(in ShaderMaterial material, in VertexInput input) { - position = input.GetPosition(); + float4 pos_nor_wind = input.GetPositionNormalWind(); + uint normal_wind = asuint(pos_nor_wind.w); + position = float4(pos_nor_wind.xyz, 1); + normal = unpack_unitvector(normal_wind); color = GetMaterial().baseColor * unpack_rgba(input.GetInstance().color); color.a *= 1 - input.GetInstancePointer().GetDither(); emissiveColor = input.GetInstance().emissive; @@ -217,7 +206,7 @@ struct VertexSurface color *= input.GetVertexColor(); } - normal = normalize(mul((float3x3)input.GetInstance().transformInverseTranspose.GetMatrix(), input.GetNormal())); + normal = normalize(mul((float3x3)input.GetInstance().transformInverseTranspose.GetMatrix(), normal)); tangent = input.GetTangent(); tangent.xyz = normalize(mul((float3x3)input.GetInstance().transformInverseTranspose.GetMatrix(), tangent.xyz)); @@ -233,7 +222,7 @@ struct VertexSurface [branch] if (material.IsUsingWind()) { - position.xyz += compute_wind(position.xyz, input.GetWindWeight()); + position.xyz += compute_wind(position.xyz, ((normal_wind >> 24u) & 0xFF) / 255.0); } #endif // DISABLE_WIND } diff --git a/WickedEngine/shaders/skinningCS.hlsl b/WickedEngine/shaders/skinningCS.hlsl index 8927215e7..de396323b 100644 --- a/WickedEngine/shaders/skinningCS.hlsl +++ b/WickedEngine/shaders/skinningCS.hlsl @@ -10,35 +10,18 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID) [branch] if (push.vb_pos_nor_wind < 0 || vertexID >= push.vertexCount) return; - - const uint fetchAddress_POS_NOR = vertexID * sizeof(float4); - const uint fetchAddress_TAN = vertexID * sizeof(uint); - const uint fetchAddress_BON = vertexID * sizeof(uint4); - - // Manual type-conversion for pos: - uint4 pos_nor_u = bindless_buffers[push.vb_pos_nor_wind].Load4(fetchAddress_POS_NOR); - float3 pos = asfloat(pos_nor_u.xyz); - - // Manual type-conversion for normal: + + float4 pos_nor_wind = bindless_buffers_float4[push.vb_pos_nor_wind][vertexID]; + uint nor_wind = asuint(pos_nor_wind.w); + + float3 pos = pos_nor_wind.xyz; float4 nor = 0; - { - nor.x = (float)((pos_nor_u.w >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - nor.y = (float)((pos_nor_u.w >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - nor.z = (float)((pos_nor_u.w >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - nor.w = (float)((pos_nor_u.w >> 24) & 0x000000FF) / 255.0f; // wind - } - - // Manual type-conversion for tangent: - float4 tan = 0; - [branch] - if (push.vb_tan >= 0) - { - uint vtan = bindless_buffers[push.vb_tan].Load(fetchAddress_TAN); - tan.x = (float)((vtan >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - tan.y = (float)((vtan >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - tan.z = (float)((vtan >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - tan.w = (float)((vtan >> 24) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - } + nor.x = (float)((nor_wind >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f; + nor.y = (float)((nor_wind >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f; + nor.z = (float)((nor_wind >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f; + nor.w = (float)((nor_wind >> 24) & 0x000000FF) / 255.0f; // wind + + float4 tan = bindless_buffers_float4[push.vb_tan][vertexID]; ByteAddressBuffer skinningbuffer = bindless_buffers[push.skinningbuffer_index]; @@ -46,17 +29,17 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID) [branch] if (push.morph_count > 0) { - ByteAddressBuffer morphvb = bindless_buffers[push.morphvb_index]; + Buffer morphvb = bindless_buffers_float4[push.morphvb_index]; for (uint morph_index = 0; morph_index < push.morph_count; ++morph_index) { MorphTargetGPU morph = skinningbuffer.Load(push.morph_offset + morph_index * sizeof(MorphTargetGPU)); if (morph.offset_pos != ~0u) { - pos += unpack_half3(morphvb.Load(morph.offset_pos + vertexID * sizeof(uint2))) * morph.weight; + pos += morphvb[morph.offset_pos + vertexID].xyz * morph.weight; } if (morph.offset_nor != ~0u) { - nor.xyz += unpack_half3(morphvb.Load(morph.offset_nor + vertexID * sizeof(uint2))) * morph.weight; + nor.xyz += morphvb[morph.offset_nor + vertexID].xyz * morph.weight; } } } @@ -71,17 +54,17 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID) if (push.vb_bon >= 0) { // Manual type-conversion for bone props: - uint4 ind_wei_u = bindless_buffers[push.vb_bon].Load4(fetchAddress_BON); + uint4 ind_wei_u = bindless_buffers[push.vb_bon].Load4(vertexID * sizeof(uint4)); - ind.x = (ind_wei_u.x >> 0) & 0x0000FFFF; - ind.y = (ind_wei_u.x >> 16) & 0x0000FFFF; - ind.z = (ind_wei_u.y >> 0) & 0x0000FFFF; - ind.w = (ind_wei_u.y >> 16) & 0x0000FFFF; + ind.x = (ind_wei_u.x >> 0) & 0xFFFF; + ind.y = (ind_wei_u.x >> 16) & 0xFFFF; + ind.z = (ind_wei_u.y >> 0) & 0xFFFF; + ind.w = (ind_wei_u.y >> 16) & 0xFFFF; - wei.x = (float)((ind_wei_u.z >> 0) & 0x0000FFFF) / 65535.0f; - wei.y = (float)((ind_wei_u.z >> 16) & 0x0000FFFF) / 65535.0f; - wei.z = (float)((ind_wei_u.w >> 0) & 0x0000FFFF) / 65535.0f; - wei.w = (float)((ind_wei_u.w >> 16) & 0x0000FFFF) / 65535.0f; + wei.x = float((ind_wei_u.z >> 0) & 0xFFFF) / 65535.0f; + wei.y = float((ind_wei_u.z >> 16) & 0xFFFF) / 65535.0f; + wei.z = float((ind_wei_u.w >> 0) & 0xFFFF) / 65535.0f; + wei.w = float((ind_wei_u.w >> 16) & 0xFFFF) / 65535.0f; } if (any(wei)) { @@ -89,10 +72,7 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID) float3 n = 0; float3 t = 0; float weisum = 0; - - // force loop to reduce register pressure - // also enabled early-exit - [loop] + for (uint i = 0; ((i < 4) && (weisum < 1.0f)); ++i) { float4x4 m = skinningbuffer.Load(push.bone_offset + ind[i] * sizeof(ShaderTransform)).GetMatrix(); @@ -114,23 +94,18 @@ void main(uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID) [branch] if (push.so_pos_nor_wind >= 0) { - pos_nor_u.xyz = asuint(pos.xyz); - pos_nor_u.w = 0; - pos_nor_u.w |= (uint)((nor.x * 0.5f + 0.5f) * 255.0f) << 0; - pos_nor_u.w |= (uint)((nor.y * 0.5f + 0.5f) * 255.0f) << 8; - pos_nor_u.w |= (uint)((nor.z * 0.5f + 0.5f) * 255.0f) << 16; - pos_nor_u.w |= (uint)(nor.w * 255.0f) << 24; // wind - bindless_rwbuffers[push.so_pos_nor_wind].Store4(fetchAddress_POS_NOR, pos_nor_u); + uint nor_wind = 0; + nor_wind |= uint((nor.x * 0.5f + 0.5f) * 255.0f) << 0; + nor_wind |= uint((nor.y * 0.5f + 0.5f) * 255.0f) << 8; + nor_wind |= uint((nor.z * 0.5f + 0.5f) * 255.0f) << 16; + nor_wind |= uint(nor.w * 255.0f) << 24; // wind + pos_nor_wind = float4(pos.xyz, asfloat(nor_wind)); + bindless_rwbuffers_float4[push.so_pos_nor_wind][vertexID] = pos_nor_wind; } [branch] if (push.so_tan >= 0) { - uint vtan = 0; - vtan |= (uint)((tan.x * 0.5f + 0.5f) * 255.0f) << 0; - vtan |= (uint)((tan.y * 0.5f + 0.5f) * 255.0f) << 8; - vtan |= (uint)((tan.z * 0.5f + 0.5f) * 255.0f) << 16; - vtan |= (uint)((tan.w * 0.5f + 0.5f) * 255.0f) << 24; - bindless_rwbuffers[push.so_tan].Store(fetchAddress_TAN, vtan); + bindless_rwbuffers_float4[push.so_tan][vertexID] = tan; } } diff --git a/WickedEngine/shaders/surfaceHF.hlsli b/WickedEngine/shaders/surfaceHF.hlsli index 7c07075fd..809c6c754 100644 --- a/WickedEngine/shaders/surfaceHF.hlsli +++ b/WickedEngine/shaders/surfaceHF.hlsli @@ -288,9 +288,9 @@ struct Surface uint i0; uint i1; uint i2; - uint4 data0; - uint4 data1; - uint4 data2; + float4 data0; + float4 data1; + float4 data2; float3 pre; bool preload_internal(PrimitiveID prim) @@ -309,15 +309,15 @@ struct Surface layerMask = material.layerMask & inst.layerMask; const uint startIndex = prim.primitiveIndex * 3 + geometry.indexOffset; - Buffer indexBuffer = bindless_ib[NonUniformResourceIndex(geometry.ib)]; + Buffer indexBuffer = bindless_buffers_uint[NonUniformResourceIndex(geometry.ib)]; i0 = indexBuffer[startIndex + 0]; i1 = indexBuffer[startIndex + 1]; i2 = indexBuffer[startIndex + 2]; - ByteAddressBuffer buf = bindless_buffers[NonUniformResourceIndex(geometry.vb_pos_nor_wind)]; - data0 = buf.Load4(i0 * sizeof(uint4)); - data1 = buf.Load4(i1 * sizeof(uint4)); - data2 = buf.Load4(i2 * sizeof(uint4)); + Buffer buf = bindless_buffers_float4[NonUniformResourceIndex(geometry.vb_pos_nor_wind)]; + data0 = buf[i0]; + data1 = buf[i1]; + data2 = buf[i2]; return true; } @@ -329,9 +329,9 @@ struct Surface const bool is_emittedparticle = geometry.flags & SHADERMESH_FLAG_EMITTEDPARTICLE; const bool simple_lighting = is_hairparticle || is_emittedparticle; - float3 n0 = unpack_unitvector(data0.w); - float3 n1 = unpack_unitvector(data1.w); - float3 n2 = unpack_unitvector(data2.w); + float3 n0 = unpack_unitvector(asuint(data0.w)); + float3 n1 = unpack_unitvector(asuint(data1.w)); + float3 n2 = unpack_unitvector(asuint(data2.w)); N = attribute_at_bary(n0, n1, n2, bary); N = mul((float3x3)inst.transformInverseTranspose.GetMatrix(), N); N = normalize(N); @@ -342,9 +342,9 @@ struct Surface facenormal = N; #ifdef SURFACE_LOAD_MIPCONE - float3 p0 = asfloat(data0.xyz); - float3 p1 = asfloat(data1.xyz); - float3 p2 = asfloat(data2.xyz); + float3 p0 = data0.xyz; + float3 p1 = data1.xyz; + float3 p2 = data2.xyz; float3 P0 = mul(inst.transform.GetMatrix(), float4(p0, 1)).xyz; float3 P1 = mul(inst.transform.GetMatrix(), float4(p1, 1)).xyz; float3 P2 = mul(inst.transform.GetMatrix(), float4(p2, 1)).xyz; @@ -363,10 +363,10 @@ struct Surface [branch] if (geometry.vb_uvs >= 0) { - ByteAddressBuffer buf = bindless_buffers[NonUniformResourceIndex(geometry.vb_uvs)]; - float4 uv0 = unpack_half4(buf.Load2(i0 * sizeof(uint2))); - float4 uv1 = unpack_half4(buf.Load2(i1 * sizeof(uint2))); - float4 uv2 = unpack_half4(buf.Load2(i2 * sizeof(uint2))); + Buffer buf = bindless_buffers_float4[NonUniformResourceIndex(geometry.vb_uvs)]; + float4 uv0 = buf[i0]; + float4 uv1 = buf[i1]; + float4 uv2 = buf[i2]; // all three must be transformed, to have correct derivatives (not enough to only transform final uvsets): uv0.xy = mad(uv0.xy, material.texMulAdd.xy, material.texMulAdd.zw); uv1.xy = mad(uv1.xy, material.texMulAdd.xy, material.texMulAdd.zw); @@ -387,12 +387,11 @@ struct Surface [branch] if (geometry.vb_tan >= 0) { - ByteAddressBuffer buf = bindless_buffers[NonUniformResourceIndex(geometry.vb_tan)]; - const float4 t0 = unpack_utangent(buf.Load(i0 * sizeof(uint))); - const float4 t1 = unpack_utangent(buf.Load(i1 * sizeof(uint))); - const float4 t2 = unpack_utangent(buf.Load(i2 * sizeof(uint))); + Buffer buf = bindless_buffers_float4[NonUniformResourceIndex(geometry.vb_tan)]; + const float4 t0 = buf[i0]; + const float4 t1 = buf[i1]; + const float4 t2 = buf[i2]; T = attribute_at_bary(t0, t1, t2, bary); - T = T * 2 - 1; T.xyz = mul((float3x3)inst.transformInverseTranspose.GetMatrix(), T.xyz); T.xyz = normalize(T.xyz); B = normalize(cross(T.xyz, N) * T.w); @@ -491,10 +490,10 @@ struct Surface [branch] if (geometry.vb_col >= 0 && material.IsUsingVertexColors()) { - ByteAddressBuffer buf = bindless_buffers[NonUniformResourceIndex(geometry.vb_col)]; - const float4 c0 = unpack_rgba(buf.Load(i0 * sizeof(uint))); - const float4 c1 = unpack_rgba(buf.Load(i1 * sizeof(uint))); - const float4 c2 = unpack_rgba(buf.Load(i2 * sizeof(uint))); + Buffer buf = bindless_buffers_float4[NonUniformResourceIndex(geometry.vb_col)]; + const float4 c0 = buf[i0]; + const float4 c1 = buf[i1]; + const float4 c2 = buf[i2]; float4 vertexColor = attribute_at_bary(c0, c1, c2, bary); baseColor *= vertexColor; } @@ -502,10 +501,10 @@ struct Surface [branch] if (inst.lightmap >= 0 && geometry.vb_atl >= 0) { - ByteAddressBuffer buf = bindless_buffers[NonUniformResourceIndex(geometry.vb_atl)]; - const float2 a0 = unpack_half2(buf.Load(i0 * sizeof(uint))); - const float2 a1 = unpack_half2(buf.Load(i1 * sizeof(uint))); - const float2 a2 = unpack_half2(buf.Load(i2 * sizeof(uint))); + Buffer buf = bindless_buffers_float2[NonUniformResourceIndex(geometry.vb_atl)]; + const float2 a0 = buf[i0]; + const float2 a1 = buf[i1]; + const float2 a2 = buf[i2]; float2 atlas = attribute_at_bary(a0, a1, a2, bary); Texture2D tex = bindless_textures[NonUniformResourceIndex(inst.lightmap)]; @@ -826,16 +825,16 @@ struct Surface [branch] if (geometry.vb_pre >= 0) { - ByteAddressBuffer buf = bindless_buffers[NonUniformResourceIndex(geometry.vb_pre)]; - pre0 = asfloat(buf.Load3(i0 * sizeof(uint4))); - pre1 = asfloat(buf.Load3(i1 * sizeof(uint4))); - pre2 = asfloat(buf.Load3(i2 * sizeof(uint4))); + Buffer buf = bindless_buffers_float4[NonUniformResourceIndex(geometry.vb_pre)]; + pre0 = buf[i0].xyz; + pre1 = buf[i1].xyz; + pre2 = buf[i2].xyz; } else { - pre0 = asfloat(data0.xyz); - pre1 = asfloat(data1.xyz); - pre2 = asfloat(data2.xyz); + pre0 = data0.xyz; + pre1 = data1.xyz; + pre2 = data2.xyz; } pre = attribute_at_bary(pre0, pre1, pre2, bary); pre = mul(inst.transformPrev.GetMatrix(), float4(pre, 1)).xyz; @@ -850,9 +849,9 @@ struct Surface bary = barycentrics; - float3 p0 = asfloat(data0.xyz); - float3 p1 = asfloat(data1.xyz); - float3 p2 = asfloat(data2.xyz); + float3 p0 = data0.xyz; + float3 p1 = data1.xyz; + float3 p2 = data2.xyz; #ifdef SURFACE_LOAD_QUAD_DERIVATIVES float3 P0 = mul(inst.transform.GetMatrix(), float4(p0, 1)).xyz; @@ -874,9 +873,9 @@ struct Surface if (!preload_internal(prim)) return false; - float3 p0 = asfloat(data0.xyz); - float3 p1 = asfloat(data1.xyz); - float3 p2 = asfloat(data2.xyz); + float3 p0 = data0.xyz; + float3 p1 = data1.xyz; + float3 p2 = data2.xyz; float3 P0 = mul(inst.transform.GetMatrix(), float4(p0, 1)).xyz; float3 P1 = mul(inst.transform.GetMatrix(), float4(p1, 1)).xyz; float3 P2 = mul(inst.transform.GetMatrix(), float4(p2, 1)).xyz; @@ -892,9 +891,9 @@ struct Surface if (!preload_internal(prim)) return false; - float3 p0 = asfloat(data0.xyz); - float3 p1 = asfloat(data1.xyz); - float3 p2 = asfloat(data2.xyz); + float3 p0 = data0.xyz; + float3 p1 = data1.xyz; + float3 p2 = data2.xyz; float3 P0 = mul(inst.transform.GetMatrix(), float4(p0, 1)).xyz; float3 P1 = mul(inst.transform.GetMatrix(), float4(p1, 1)).xyz; float3 P2 = mul(inst.transform.GetMatrix(), float4(p2, 1)).xyz; @@ -903,9 +902,9 @@ struct Surface [branch] if (material.IsUsingWind()) { - float wind0 = ((data0.w >> 24u) & 0xFF) / 255.0; - float wind1 = ((data1.w >> 24u) & 0xFF) / 255.0; - float wind2 = ((data2.w >> 24u) & 0xFF) / 255.0; + float wind0 = ((asuint(data0.w) >> 24u) & 0xFF) / 255.0; + float wind1 = ((asuint(data1.w) >> 24u) & 0xFF) / 255.0; + float wind2 = ((asuint(data2.w) >> 24u) & 0xFF) / 255.0; // this is hella slow to do per pixel: P0 += compute_wind(P0, wind0); @@ -938,9 +937,9 @@ struct Surface if (!preload_internal(prim)) return false; - float3 p0 = asfloat(data0.xyz); - float3 p1 = asfloat(data1.xyz); - float3 p2 = asfloat(data2.xyz); + float3 p0 = data0.xyz; + float3 p1 = data1.xyz; + float3 p2 = data2.xyz; float3 P0 = mul(inst.transform.GetMatrix(), float4(p0, 1)).xyz; float3 P1 = mul(inst.transform.GetMatrix(), float4(p1, 1)).xyz; float3 P2 = mul(inst.transform.GetMatrix(), float4(p2, 1)).xyz; @@ -949,9 +948,9 @@ struct Surface [branch] if (material.IsUsingWind()) { - float wind0 = ((data0.w >> 24u) & 0xFF) / 255.0; - float wind1 = ((data1.w >> 24u) & 0xFF) / 255.0; - float wind2 = ((data2.w >> 24u) & 0xFF) / 255.0; + float wind0 = ((asuint(data0.w) >> 24u) & 0xFF) / 255.0; + float wind1 = ((asuint(data1.w) >> 24u) & 0xFF) / 255.0; + float wind2 = ((asuint(data2.w) >> 24u) & 0xFF) / 255.0; // this is hella slow to do per pixel: P0 += compute_wind(P0, wind0); diff --git a/WickedEngine/shaders/tonemapCS.hlsl b/WickedEngine/shaders/tonemapCS.hlsl index 94e8187a5..106c12227 100644 --- a/WickedEngine/shaders/tonemapCS.hlsl +++ b/WickedEngine/shaders/tonemapCS.hlsl @@ -63,22 +63,38 @@ float4x4 saturationMatrix(float saturation) [RootSignature( "RootConstants(num32BitConstants=16, b999)," "DescriptorTable( " - "SRV(t0, space = 2, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," - "SRV(t0, space = 3, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," - "SRV(t0, space = 4, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," - "SRV(t0, space = 5, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," - "SRV(t0, space = 6, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," - "SRV(t0, space = 7, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," - "SRV(t0, space = 8, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," - "SRV(t0, space = 9, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," - "SRV(t0, space = 10, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," - "SRV(t0, space = 11, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," - "SRV(t0, space = 12, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," - "SRV(t0, space = 13, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," - "UAV(u0, space = 14, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," - "UAV(u0, space = 15, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," - "UAV(u0, space = 16, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," - "UAV(u0, space = 17, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)" + "SRV(t0, space = 2, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 3, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 4, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 5, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 6, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 7, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 8, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 9, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 10, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 11, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 12, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 13, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 14, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 15, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 16, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 17, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 18, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 19, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "SRV(t0, space = 20, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 21, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 22, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 23, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 24, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 25, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 26, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 27, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 28, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 29, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 30, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 31, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 32, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)," + "UAV(u0, space = 33, offset = 0, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE | DATA_VOLATILE)" "), " "StaticSampler(s100, addressU = TEXTURE_ADDRESS_CLAMP, addressV = TEXTURE_ADDRESS_CLAMP, addressW = TEXTURE_ADDRESS_CLAMP, filter = FILTER_MIN_MAG_MIP_LINEAR)" )] diff --git a/WickedEngine/wiEmittedParticle.cpp b/WickedEngine/wiEmittedParticle.cpp index cf11576aa..d5905df5e 100644 --- a/WickedEngine/wiEmittedParticle.cpp +++ b/WickedEngine/wiEmittedParticle.cpp @@ -121,22 +121,22 @@ namespace wi vb_pos.offset = buffer_offset; buffer_offset += AlignTo(vb_pos.size, alignment); - vb_pos.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_pos.offset, vb_pos.size); - vb_pos.subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_pos.offset, vb_pos.size); + vb_pos.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_pos.offset, vb_pos.size, &MeshComponent::Vertex_POS::FORMAT); + vb_pos.subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_pos.offset, vb_pos.size, &MeshComponent::Vertex_POS::FORMAT); vb_pos.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_pos.subresource_srv); vb_pos.descriptor_uav = device->GetDescriptorIndex(&generalBuffer, SubresourceType::UAV, vb_pos.subresource_uav); vb_uvs.offset = buffer_offset; buffer_offset += AlignTo(vb_uvs.size, alignment); - vb_uvs.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_uvs.offset, vb_uvs.size); - vb_uvs.subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_uvs.offset, vb_uvs.size); + vb_uvs.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_uvs.offset, vb_uvs.size, &MeshComponent::Vertex_UVS::FORMAT); + vb_uvs.subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_uvs.offset, vb_uvs.size, &MeshComponent::Vertex_UVS::FORMAT); vb_uvs.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_uvs.subresource_srv); vb_uvs.descriptor_uav = device->GetDescriptorIndex(&generalBuffer, SubresourceType::UAV, vb_uvs.subresource_uav); vb_col.offset = buffer_offset; buffer_offset += AlignTo(vb_col.size, alignment); - vb_col.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_col.offset, vb_col.size); - vb_col.subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_col.offset, vb_col.size); + vb_col.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_col.offset, vb_col.size, &MeshComponent::Vertex_COL::FORMAT); + vb_col.subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_col.offset, vb_col.size, &MeshComponent::Vertex_COL::FORMAT); vb_col.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_col.subresource_srv); vb_col.descriptor_uav = device->GetDescriptorIndex(&generalBuffer, SubresourceType::UAV, vb_col.subresource_uav); @@ -365,8 +365,7 @@ namespace wi cb.xEmitterTransform.Create(transform.world); cb.xEmitCount = (uint32_t)emit; cb.xEmitterMeshIndexCount = mesh == nullptr ? 0 : (uint32_t)mesh->indices.size(); - cb.xEmitterMeshVertexPositionStride = sizeof(MeshComponent::Vertex_POS); - cb.xEmitterRandomness = wi::random::GetRandom(0, 1000) * 0.001f; + cb.xEmitterRandomness = wi::random::GetRandom(0.0f, 1.0f); cb.xParticleLifeSpan = life; cb.xParticleLifeSpanRandomness = random_life; cb.xParticleNormalFactor = normal_factor; diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.cpp b/WickedEngine/wiGraphicsDevice_Vulkan.cpp index 732a7d509..a1ac25b5b 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.cpp +++ b/WickedEngine/wiGraphicsDevice_Vulkan.cpp @@ -363,9 +363,9 @@ namespace vulkan_internal switch (value) { case ShaderStage::MS: - return VK_SHADER_STAGE_MESH_BIT_NV; + return VK_SHADER_STAGE_MESH_BIT_EXT; case ShaderStage::AS: - return VK_SHADER_STAGE_TASK_BIT_NV; + return VK_SHADER_STAGE_TASK_BIT_EXT; case ShaderStage::VS: return VK_SHADER_STAGE_VERTEX_BIT; case ShaderStage::HS: @@ -3293,8 +3293,12 @@ using namespace vulkan_internal; pso_dynamicStates.push_back(VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE); dynamicStateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dynamicStateInfo.dynamicStateCount = (uint32_t)pso_dynamicStates.size(); dynamicStateInfo.pDynamicStates = pso_dynamicStates.data(); + dynamicStateInfo.dynamicStateCount = (uint32_t)pso_dynamicStates.size(); + + dynamicStateInfo_MeshShader.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dynamicStateInfo_MeshShader.pDynamicStates = pso_dynamicStates.data(); + dynamicStateInfo_MeshShader.dynamicStateCount = (uint32_t)pso_dynamicStates.size() - 1; // don't include VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE for mesh shader // Note: limiting descriptors by constant amount is needed, because the bindless sets are bound to multiple slots to match DX12 layout // And binding to multiple slot adds up towards limits, so the limits will be quickly reached for some descriptor types @@ -4474,10 +4478,10 @@ using namespace vulkan_internal; switch (stage) { case ShaderStage::MS: - internal_state->stageInfo.stage = VK_SHADER_STAGE_MESH_BIT_NV; + internal_state->stageInfo.stage = VK_SHADER_STAGE_MESH_BIT_EXT; break; case ShaderStage::AS: - internal_state->stageInfo.stage = VK_SHADER_STAGE_TASK_BIT_NV; + internal_state->stageInfo.stage = VK_SHADER_STAGE_TASK_BIT_EXT; break; case ShaderStage::VS: internal_state->stageInfo.stage = VK_SHADER_STAGE_VERTEX_BIT; @@ -4538,6 +4542,8 @@ using namespace vulkan_internal; for (auto& x : bindings) { + if (x->accessed == 0) + continue; const bool bindless = x->set > 0; if (bindless) @@ -4554,9 +4560,7 @@ using namespace vulkan_internal; descriptor.descriptorType = (VkDescriptorType)x->descriptor_type; if (bindless) - { continue; - } auto& imageViewType = internal_state->imageViewTypes.emplace_back(); imageViewType = VK_IMAGE_VIEW_TYPE_MAX_ENUM; @@ -5504,7 +5508,14 @@ using namespace vulkan_internal; pipelineInfo.pTessellationState = &tessellationInfo; - pipelineInfo.pDynamicState = &dynamicStateInfo; + if (pso->desc.ms == nullptr) + { + pipelineInfo.pDynamicState = &dynamicStateInfo; + } + else + { + pipelineInfo.pDynamicState = &dynamicStateInfo_MeshShader; + } if (renderpass_info != nullptr) { diff --git a/WickedEngine/wiGraphicsDevice_Vulkan.h b/WickedEngine/wiGraphicsDevice_Vulkan.h index 0a20e6114..f00e2d8bf 100644 --- a/WickedEngine/wiGraphicsDevice_Vulkan.h +++ b/WickedEngine/wiGraphicsDevice_Vulkan.h @@ -85,6 +85,7 @@ namespace wi::graphics wi::vector pso_dynamicStates; VkPipelineDynamicStateCreateInfo dynamicStateInfo = {}; + VkPipelineDynamicStateCreateInfo dynamicStateInfo_MeshShader = {}; VkBuffer nullBuffer = VK_NULL_HANDLE; VmaAllocation nullBufferAllocation = VK_NULL_HANDLE; diff --git a/WickedEngine/wiHairParticle.cpp b/WickedEngine/wiHairParticle.cpp index c3b4cbd89..4d72c5a1b 100644 --- a/WickedEngine/wiHairParticle.cpp +++ b/WickedEngine/wiHairParticle.cpp @@ -141,24 +141,24 @@ namespace wi buffer_offset = AlignTo(buffer_offset, alignment); vb_pos[0].offset = buffer_offset; - vb_pos[0].subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_pos[0].offset, vb_pos[0].size); - vb_pos[0].subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_pos[0].offset, vb_pos[0].size); + vb_pos[0].subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_pos[0].offset, vb_pos[0].size, &MeshComponent::Vertex_POS::FORMAT); + vb_pos[0].subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_pos[0].offset, vb_pos[0].size, &MeshComponent::Vertex_POS::FORMAT); vb_pos[0].descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_pos[0].subresource_srv); vb_pos[0].descriptor_uav = device->GetDescriptorIndex(&generalBuffer, SubresourceType::UAV, vb_pos[0].subresource_uav); buffer_offset += vb_pos[0].size; buffer_offset = AlignTo(buffer_offset, alignment); vb_pos[1].offset = buffer_offset; - vb_pos[1].subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_pos[1].offset, vb_pos[1].size); - vb_pos[1].subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_pos[1].offset, vb_pos[1].size); + vb_pos[1].subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_pos[1].offset, vb_pos[1].size, &MeshComponent::Vertex_POS::FORMAT); + vb_pos[1].subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_pos[1].offset, vb_pos[1].size, &MeshComponent::Vertex_POS::FORMAT); vb_pos[1].descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_pos[1].subresource_srv); vb_pos[1].descriptor_uav = device->GetDescriptorIndex(&generalBuffer, SubresourceType::UAV, vb_pos[1].subresource_uav); buffer_offset += vb_pos[1].size; buffer_offset = AlignTo(buffer_offset, alignment); vb_uvs.offset = buffer_offset; - vb_uvs.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_uvs.offset, vb_uvs.size); - vb_uvs.subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_uvs.offset, vb_uvs.size); + vb_uvs.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_uvs.offset, vb_uvs.size, &MeshComponent::Vertex_UVS::FORMAT); + vb_uvs.subresource_uav = device->CreateSubresource(&generalBuffer, SubresourceType::UAV, vb_uvs.offset, vb_uvs.size, &MeshComponent::Vertex_UVS::FORMAT); vb_uvs.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_uvs.subresource_srv); vb_uvs.descriptor_uav = device->GetDescriptorIndex(&generalBuffer, SubresourceType::UAV, vb_uvs.subresource_uav); buffer_offset += vb_uvs.size; diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 0e6e3a802..bffad88ca 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -4176,7 +4176,7 @@ void UpdateRenderData( { push.morph_count = mesh.active_morph_count; push.morph_offset = mesh.morphGPUOffset; - push.morphvb_index = device->GetDescriptorIndex(&mesh.generalBuffer, SubresourceType::SRV); + push.morphvb_index = mesh.vb_mor.descriptor_srv; } else { diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp index 285c9fec3..fa891acda 100644 --- a/WickedEngine/wiScene.cpp +++ b/WickedEngine/wiScene.cpp @@ -66,7 +66,7 @@ namespace wi::scene desc.stride = sizeof(ShaderMeshInstance); desc.size = desc.stride * instanceArraySize * 2; // *2 to grow fast desc.bind_flags = BindFlag::SHADER_RESOURCE; - desc.misc_flags = ResourceMiscFlag::BUFFER_RAW; + desc.misc_flags = ResourceMiscFlag::BUFFER_STRUCTURED; if (!device->CheckCapability(GraphicsDeviceCapability::CACHE_COHERENT_UMA)) { // Non-UMA: separate Default usage buffer @@ -99,7 +99,7 @@ namespace wi::scene desc.stride = sizeof(ShaderMaterial); desc.size = desc.stride * materialArraySize * 2; // *2 to grow fast desc.bind_flags = BindFlag::SHADER_RESOURCE; - desc.misc_flags = ResourceMiscFlag::BUFFER_RAW; + desc.misc_flags = ResourceMiscFlag::BUFFER_STRUCTURED; if (!device->CheckCapability(GraphicsDeviceCapability::CACHE_COHERENT_UMA)) { // Non-UMA: separate Default usage buffer @@ -253,7 +253,7 @@ namespace wi::scene desc.stride = sizeof(ShaderGeometry); desc.size = desc.stride * geometryArraySize * 2; // *2 to grow fast desc.bind_flags = BindFlag::SHADER_RESOURCE; - desc.misc_flags = ResourceMiscFlag::BUFFER_RAW; + desc.misc_flags = ResourceMiscFlag::BUFFER_STRUCTURED; if (!device->CheckCapability(GraphicsDeviceCapability::CACHE_COHERENT_UMA)) { // Non-UMA: separate Default usage buffer @@ -356,7 +356,7 @@ namespace wi::scene desc.stride = sizeof(ShaderMeshlet); desc.size = desc.stride * meshletCount * 2; // *2 to grow fast desc.bind_flags = BindFlag::SHADER_RESOURCE | BindFlag::UNORDERED_ACCESS; - desc.misc_flags = ResourceMiscFlag::BUFFER_RAW; + desc.misc_flags = ResourceMiscFlag::BUFFER_STRUCTURED; bool success = device->CreateBuffer(&desc, nullptr, &meshletBuffer); assert(success); device->SetName(&meshletBuffer, "meshletBuffer"); @@ -679,7 +679,7 @@ namespace wi::scene desc.size = AlignTo(AlignTo(sizeof(IndirectDrawArgsIndexedInstanced), alignment), sizeof(IndirectDrawArgsIndexedInstanced)) + // indirect args, additional structured buffer alignment AlignTo(allocated_impostor_capacity * sizeof(uint) * 6, alignment) + // indices (must overestimate here for 32-bit indices, because we create 16 bit and 32 bit descriptors) - AlignTo(allocated_impostor_capacity * sizeof(uint4) * 4, alignment) + // vertices + AlignTo(allocated_impostor_capacity * sizeof(MeshComponent::Vertex_POS) * 4, alignment) + // vertices AlignTo(allocated_impostor_capacity * sizeof(uint2), alignment) // impostordata ; device->CreateBuffer(&desc, nullptr, &impostorBuffer); @@ -715,9 +715,9 @@ namespace wi::scene buffer_offset = AlignTo(buffer_offset, alignment); impostor_vb.offset = buffer_offset; - impostor_vb.size = allocated_impostor_capacity * sizeof(uint4) * 4; - impostor_vb.subresource_srv = device->CreateSubresource(&impostorBuffer, SubresourceType::SRV, impostor_vb.offset, impostor_vb.size); - impostor_vb.subresource_uav = device->CreateSubresource(&impostorBuffer, SubresourceType::UAV, impostor_vb.offset, impostor_vb.size); + impostor_vb.size = allocated_impostor_capacity * sizeof(MeshComponent::Vertex_POS) * 4; + impostor_vb.subresource_srv = device->CreateSubresource(&impostorBuffer, SubresourceType::SRV, impostor_vb.offset, impostor_vb.size, &MeshComponent::Vertex_POS::FORMAT); + impostor_vb.subresource_uav = device->CreateSubresource(&impostorBuffer, SubresourceType::UAV, impostor_vb.offset, impostor_vb.size, &MeshComponent::Vertex_POS::FORMAT); impostor_vb.descriptor_srv = device->GetDescriptorIndex(&impostorBuffer, SubresourceType::SRV, impostor_vb.subresource_srv); impostor_vb.descriptor_uav = device->GetDescriptorIndex(&impostorBuffer, SubresourceType::UAV, impostor_vb.subresource_uav); buffer_offset += impostor_vb.size; diff --git a/WickedEngine/wiScene_Components.cpp b/WickedEngine/wiScene_Components.cpp index bcb4ba41f..b9ae453b7 100644 --- a/WickedEngine/wiScene_Components.cpp +++ b/WickedEngine/wiScene_Components.cpp @@ -579,15 +579,17 @@ namespace wi::scene AlignTo(vertex_boneindices.size() * sizeof(Vertex_BON), alignment) ; + constexpr Format morph_format = Format::R16G16B16A16_FLOAT; + constexpr size_t morph_stride = GetFormatStride(morph_format); for (MorphTarget& morph : morph_targets) { if (!morph.vertex_positions.empty()) { - bd.size += AlignTo(vertex_positions.size() * sizeof(XMHALF4), alignment); + bd.size += AlignTo(vertex_positions.size() * morph_stride, alignment); } if (!morph.vertex_normals.empty()) { - bd.size += AlignTo(vertex_normals.size() * sizeof(XMHALF4), alignment); + bd.size += AlignTo(vertex_normals.size() * morph_stride, alignment); } } @@ -735,11 +737,12 @@ namespace wi::scene // morph buffers: if (!morph_targets.empty()) { + vb_mor.offset = buffer_offset; for (MorphTarget& morph : morph_targets) { if (!morph.vertex_positions.empty()) { - morph.offset_pos = buffer_offset; + morph.offset_pos = (buffer_offset - vb_mor.offset) / morph_stride; XMHALF4* vertices = (XMHALF4*)(buffer_data + buffer_offset); std::fill(vertices, vertices + vertex_positions.size(), 0); if (morph.sparse_indices_positions.empty()) @@ -763,7 +766,7 @@ namespace wi::scene } if (!morph.vertex_normals.empty()) { - morph.offset_nor = buffer_offset; + morph.offset_nor = (buffer_offset - vb_mor.offset) / morph_stride; XMHALF4* vertices = (XMHALF4*)(buffer_data + buffer_offset); std::fill(vertices, vertices + vertex_normals.size(), 0); if (morph.sparse_indices_normals.empty()) @@ -786,6 +789,7 @@ namespace wi::scene buffer_offset += AlignTo(morph.vertex_normals.size() * sizeof(XMHALF4), alignment); } } + vb_mor.size = buffer_offset - vb_mor.offset; } }; @@ -799,27 +803,27 @@ namespace wi::scene ib.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, ib.subresource_srv); assert(vb_pos_nor_wind.IsValid()); - vb_pos_nor_wind.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_pos_nor_wind.offset, vb_pos_nor_wind.size); + vb_pos_nor_wind.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_pos_nor_wind.offset, vb_pos_nor_wind.size, &Vertex_POS::FORMAT); vb_pos_nor_wind.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_pos_nor_wind.subresource_srv); if (vb_tan.IsValid()) { - vb_tan.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_tan.offset, vb_tan.size); + vb_tan.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_tan.offset, vb_tan.size, &Vertex_TAN::FORMAT); vb_tan.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_tan.subresource_srv); } if (vb_uvs.IsValid()) { - vb_uvs.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_uvs.offset, vb_uvs.size); + vb_uvs.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_uvs.offset, vb_uvs.size, &Vertex_UVS::FORMAT); vb_uvs.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_uvs.subresource_srv); } if (vb_atl.IsValid()) { - vb_atl.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_atl.offset, vb_atl.size); + vb_atl.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_atl.offset, vb_atl.size, &Vertex_TEX::FORMAT); vb_atl.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_atl.subresource_srv); } if (vb_col.IsValid()) { - vb_col.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_col.offset, vb_col.size); + vb_col.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_col.offset, vb_col.size, &Vertex_COL::FORMAT); vb_col.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_col.subresource_srv); } if (vb_bon.IsValid()) @@ -827,6 +831,11 @@ namespace wi::scene vb_bon.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_bon.offset, vb_bon.size); vb_bon.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_bon.subresource_srv); } + if (vb_mor.IsValid()) + { + vb_mor.subresource_srv = device->CreateSubresource(&generalBuffer, SubresourceType::SRV, vb_mor.offset, vb_mor.size, &morph_format); + vb_mor.descriptor_srv = device->GetDescriptorIndex(&generalBuffer, SubresourceType::SRV, vb_mor.subresource_srv); + } if (!vertex_boneindices.empty() || !morph_targets.empty()) { @@ -860,8 +869,8 @@ namespace wi::scene so_pos_nor_wind.offset = buffer_offset; so_pos_nor_wind.size = vb_pos_nor_wind.size; buffer_offset += AlignTo(so_pos_nor_wind.size, alignment); - so_pos_nor_wind.subresource_srv = device->CreateSubresource(&streamoutBuffer, SubresourceType::SRV, so_pos_nor_wind.offset, so_pos_nor_wind.size); - so_pos_nor_wind.subresource_uav = device->CreateSubresource(&streamoutBuffer, SubresourceType::UAV, so_pos_nor_wind.offset, so_pos_nor_wind.size); + so_pos_nor_wind.subresource_srv = device->CreateSubresource(&streamoutBuffer, SubresourceType::SRV, so_pos_nor_wind.offset, so_pos_nor_wind.size, &Vertex_POS::FORMAT); + so_pos_nor_wind.subresource_uav = device->CreateSubresource(&streamoutBuffer, SubresourceType::UAV, so_pos_nor_wind.offset, so_pos_nor_wind.size, &Vertex_POS::FORMAT); so_pos_nor_wind.descriptor_srv = device->GetDescriptorIndex(&streamoutBuffer, SubresourceType::SRV, so_pos_nor_wind.subresource_srv); so_pos_nor_wind.descriptor_uav = device->GetDescriptorIndex(&streamoutBuffer, SubresourceType::UAV, so_pos_nor_wind.subresource_uav); @@ -870,8 +879,8 @@ namespace wi::scene so_tan.offset = buffer_offset; so_tan.size = vb_tan.size; buffer_offset += AlignTo(so_tan.size, alignment); - so_tan.subresource_srv = device->CreateSubresource(&streamoutBuffer, SubresourceType::SRV, so_tan.offset, so_tan.size); - so_tan.subresource_uav = device->CreateSubresource(&streamoutBuffer, SubresourceType::UAV, so_tan.offset, so_tan.size); + so_tan.subresource_srv = device->CreateSubresource(&streamoutBuffer, SubresourceType::SRV, so_tan.offset, so_tan.size, &Vertex_TAN::FORMAT); + so_tan.subresource_uav = device->CreateSubresource(&streamoutBuffer, SubresourceType::UAV, so_tan.offset, so_tan.size, &Vertex_TAN::FORMAT); so_tan.descriptor_srv = device->GetDescriptorIndex(&streamoutBuffer, SubresourceType::SRV, so_tan.subresource_srv); so_tan.descriptor_uav = device->GetDescriptorIndex(&streamoutBuffer, SubresourceType::UAV, so_tan.subresource_uav); } @@ -879,8 +888,8 @@ namespace wi::scene so_pre.offset = buffer_offset; so_pre.size = vb_pos_nor_wind.size; buffer_offset += AlignTo(so_pre.size, alignment); - so_pre.subresource_srv = device->CreateSubresource(&streamoutBuffer, SubresourceType::SRV, so_pre.offset, so_pre.size); - so_pre.subresource_uav = device->CreateSubresource(&streamoutBuffer, SubresourceType::UAV, so_pre.offset, so_pre.size); + so_pre.subresource_srv = device->CreateSubresource(&streamoutBuffer, SubresourceType::SRV, so_pre.offset, so_pre.size, &Vertex_POS::FORMAT); + so_pre.subresource_uav = device->CreateSubresource(&streamoutBuffer, SubresourceType::UAV, so_pre.offset, so_pre.size, &Vertex_POS::FORMAT); so_pre.descriptor_srv = device->GetDescriptorIndex(&streamoutBuffer, SubresourceType::SRV, so_pre.subresource_srv); so_pre.descriptor_uav = device->GetDescriptorIndex(&streamoutBuffer, SubresourceType::UAV, so_pre.subresource_uav); } diff --git a/WickedEngine/wiScene_Components.h b/WickedEngine/wiScene_Components.h index 8da93c137..06540110f 100644 --- a/WickedEngine/wiScene_Components.h +++ b/WickedEngine/wiScene_Components.h @@ -409,6 +409,7 @@ namespace wi::scene BufferView vb_atl; BufferView vb_col; BufferView vb_bon; + BufferView vb_mor; BufferView so_pos_nor_wind; BufferView so_tan; BufferView so_pre; @@ -498,7 +499,7 @@ namespace wi::scene XMFLOAT3 pos = XMFLOAT3(0.0f, 0.0f, 0.0f); uint32_t normal_wind = 0; - void FromFULL(const XMFLOAT3& _pos, const XMFLOAT3& _nor, uint8_t wind) + constexpr void FromFULL(const XMFLOAT3& _pos, const XMFLOAT3& _nor, uint8_t wind) { pos.x = _pos.x; pos.y = _pos.y; @@ -514,39 +515,37 @@ namespace wi::scene XMFLOAT3 N = GetNor_FULL(); return XMLoadFloat3(&N); } - inline void MakeFromParams(const XMFLOAT3& normal) + constexpr void MakeFromParams(const XMFLOAT3& normal) { normal_wind = normal_wind & 0xFF000000; // reset only the normals - - normal_wind |= (uint32_t)((normal.x * 0.5f + 0.5f) * 255.0f) << 0; - normal_wind |= (uint32_t)((normal.y * 0.5f + 0.5f) * 255.0f) << 8; - normal_wind |= (uint32_t)((normal.z * 0.5f + 0.5f) * 255.0f) << 16; + normal_wind |= uint32_t((normal.x * 0.5f + 0.5f) * 255.0f) << 0; + normal_wind |= uint32_t((normal.y * 0.5f + 0.5f) * 255.0f) << 8; + normal_wind |= uint32_t((normal.z * 0.5f + 0.5f) * 255.0f) << 16; } - inline void MakeFromParams(const XMFLOAT3& normal, uint8_t wind) + constexpr void MakeFromParams(const XMFLOAT3& normal, uint8_t wind) { normal_wind = 0; - - normal_wind |= (uint32_t)((normal.x * 0.5f + 0.5f) * 255.0f) << 0; - normal_wind |= (uint32_t)((normal.y * 0.5f + 0.5f) * 255.0f) << 8; - normal_wind |= (uint32_t)((normal.z * 0.5f + 0.5f) * 255.0f) << 16; - normal_wind |= (uint32_t)wind << 24; + normal_wind |= uint32_t((normal.x * 0.5f + 0.5f) * 255.0f) << 0; + normal_wind |= uint32_t((normal.y * 0.5f + 0.5f) * 255.0f) << 8; + normal_wind |= uint32_t((normal.z * 0.5f + 0.5f) * 255.0f) << 16; + normal_wind |= uint32_t(wind) << 24; } - inline XMFLOAT3 GetNor_FULL() const + constexpr XMFLOAT3 GetNor_FULL() const { XMFLOAT3 nor_FULL(0, 0, 0); - nor_FULL.x = (float)((normal_wind >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - nor_FULL.y = (float)((normal_wind >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f; - nor_FULL.z = (float)((normal_wind >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f; + nor_FULL.x = (float((normal_wind >> 0) & 0xFF) / 255.0f) * 2.0f - 1.0f; + nor_FULL.y = (float((normal_wind >> 8) & 0xFF) / 255.0f) * 2.0f - 1.0f; + nor_FULL.z = (float((normal_wind >> 16) & 0xFF) / 255.0f) * 2.0f - 1.0f; return nor_FULL; } - inline uint8_t GetWind() const + constexpr uint8_t GetWind() const { - return (normal_wind >> 24) & 0x000000FF; + return (normal_wind >> 24) & 0xFF; } - static const wi::graphics::Format FORMAT = wi::graphics::Format::R32G32B32A32_FLOAT; + static constexpr wi::graphics::Format FORMAT = wi::graphics::Format::R32G32B32A32_FLOAT; }; struct Vertex_TEX { @@ -557,64 +556,63 @@ namespace wi::scene tex = XMHALF2(texcoords.x, texcoords.y); } - static const wi::graphics::Format FORMAT = wi::graphics::Format::R16G16_FLOAT; + static constexpr wi::graphics::Format FORMAT = wi::graphics::Format::R16G16_FLOAT; }; struct Vertex_UVS { Vertex_TEX uv0; Vertex_TEX uv1; + static constexpr wi::graphics::Format FORMAT = wi::graphics::Format::R16G16B16A16_FLOAT; }; struct Vertex_BON { - uint64_t ind = 0; - uint64_t wei = 0; + uint16_t ind0 = 0; + uint16_t ind1 = 0; + uint16_t ind2 = 0; + uint16_t ind3 = 0; - void FromFULL(const XMUINT4& boneIndices, const XMFLOAT4& boneWeights) + uint16_t wei0 = 0; + uint16_t wei1 = 1; + uint16_t wei2 = 2; + uint16_t wei3 = 3; + + constexpr void FromFULL(const XMUINT4& boneIndices, const XMFLOAT4& boneWeights) { - ind = 0; - wei = 0; + ind0 = uint16_t(boneIndices.x); + ind1 = uint16_t(boneIndices.y); + ind2 = uint16_t(boneIndices.z); + ind3 = uint16_t(boneIndices.w); - ind |= (uint64_t)boneIndices.x << 0; - ind |= (uint64_t)boneIndices.y << 16; - ind |= (uint64_t)boneIndices.z << 32; - ind |= (uint64_t)boneIndices.w << 48; - - wei |= (uint64_t)(boneWeights.x * 65535.0f) << 0; - wei |= (uint64_t)(boneWeights.y * 65535.0f) << 16; - wei |= (uint64_t)(boneWeights.z * 65535.0f) << 32; - wei |= (uint64_t)(boneWeights.w * 65535.0f) << 48; + wei0 = uint16_t(boneWeights.x * 65535.0f); + wei1 = uint16_t(boneWeights.y * 65535.0f); + wei2 = uint16_t(boneWeights.z * 65535.0f); + wei3 = uint16_t(boneWeights.w * 65535.0f); } - inline XMUINT4 GetInd_FULL() const + constexpr XMUINT4 GetInd_FULL() const { - XMUINT4 ind_FULL(0, 0, 0, 0); - - ind_FULL.x = ((ind >> 0) & 0x0000FFFF); - ind_FULL.y = ((ind >> 16) & 0x0000FFFF); - ind_FULL.z = ((ind >> 32) & 0x0000FFFF); - ind_FULL.w = ((ind >> 48) & 0x0000FFFF); - - return ind_FULL; + return XMUINT4(ind0, ind1, ind2, ind3); } - inline XMFLOAT4 GetWei_FULL() const + constexpr XMFLOAT4 GetWei_FULL() const { - XMFLOAT4 wei_FULL(0, 0, 0, 0); - - wei_FULL.x = (float)((wei >> 0) & 0x0000FFFF) / 65535.0f; - wei_FULL.y = (float)((wei >> 16) & 0x0000FFFF) / 65535.0f; - wei_FULL.z = (float)((wei >> 32) & 0x0000FFFF) / 65535.0f; - wei_FULL.w = (float)((wei >> 48) & 0x0000FFFF) / 65535.0f; - - return wei_FULL; + return XMFLOAT4( + float(wei0) / 65535.0f, + float(wei1) / 65535.0f, + float(wei2) / 65535.0f, + float(wei3) / 65535.0f + ); } }; struct Vertex_COL { uint32_t color = 0; - static const wi::graphics::Format FORMAT = wi::graphics::Format::R8G8B8A8_UNORM; + static constexpr wi::graphics::Format FORMAT = wi::graphics::Format::R8G8B8A8_UNORM; }; struct Vertex_TAN { - uint32_t tangent = 0; + int8_t x = 0; + int8_t y = 0; + int8_t z = 0; + int8_t w = 0; void FromFULL(const XMFLOAT4& tan) { @@ -623,14 +621,14 @@ namespace wi::scene XMFLOAT4 t; XMStoreFloat4(&t, T); t.w = tan.w; - tangent = 0; - tangent |= (uint)((t.x * 0.5f + 0.5f) * 255.0f) << 0; - tangent |= (uint)((t.y * 0.5f + 0.5f) * 255.0f) << 8; - tangent |= (uint)((t.z * 0.5f + 0.5f) * 255.0f) << 16; - tangent |= (uint)((t.w * 0.5f + 0.5f) * 255.0f) << 24; + + x = int8_t(t.x * 127.0f); + y = int8_t(t.y * 127.0f); + z = int8_t(t.z * 127.0f); + w = int8_t(t.w * 127.0f); } - static const wi::graphics::Format FORMAT = wi::graphics::Format::R8G8B8A8_UNORM; + static constexpr wi::graphics::Format FORMAT = wi::graphics::Format::R8G8B8A8_SNORM; }; }; diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index b55e80a73..6cb119c67 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 256; + const int revision = 257; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);