shader buffer refactor; vulkan mesh shader fixes; (#713)

This commit is contained in:
Turánszki János
2023-07-25 09:59:59 +02:00
committed by GitHub
parent 532ed92ac4
commit 484f32f3e4
29 changed files with 685 additions and 507 deletions
+1 -1
View File
@@ -102,7 +102,7 @@ jobs:
- name: Package Content
uses: actions/upload-artifact@v2
with:
name: Additional Content
name: Content
path: |
Content/models
Content/scripts
+1 -1
View File
@@ -102,7 +102,7 @@ jobs:
- name: Package Content
uses: actions/upload-artifact@v2
with:
name: Additional Content
name: Content
path: |
Content/models
Content/scripts
+1 -1
View File
@@ -103,7 +103,7 @@ jobs:
- name: Package Content
uses: actions/upload-artifact@v2
with:
name: Additional Content
name: Content
path: |
Content/models
Content/scripts
+165 -27
View File
@@ -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 <spirv/unified1/spirv.h>
#else
#include "./include/spirv/unified1/spirv.h"
#endif
#include <stdint.h>
#include <string.h>
@@ -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 <cstdlib>
#include <string>
#include <vector>
@@ -1368,11 +1486,14 @@ namespace spv_reflect {
class ShaderModule {
public:
ShaderModule();
ShaderModule(size_t size, const void* p_code);
ShaderModule(const std::vector<uint8_t>& code);
ShaderModule(const std::vector<uint32_t>& code);
ShaderModule(size_t size, const void* p_code, SpvReflectModuleFlags flags = SPV_REFLECT_MODULE_FLAG_NONE);
ShaderModule(const std::vector<uint8_t>& code, SpvReflectModuleFlags flags = SPV_REFLECT_MODULE_FLAG_NONE);
ShaderModule(const std::vector<uint32_t>& 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<uint8_t>& code) {
m_result = spvReflectCreateShaderModule(
inline ShaderModule::ShaderModule(const std::vector<uint8_t>& code, SpvReflectModuleFlags flags) {
m_result = spvReflectCreateShaderModule2(
flags,
code.size(),
code.data(),
&m_module);
@@ -1499,10 +1622,11 @@ inline ShaderModule::ShaderModule(const std::vector<uint8_t>& code) {
/*! @fn ShaderModule
@param code
*/
inline ShaderModule::ShaderModule(const std::vector<uint32_t>& code) {
m_result = spvReflectCreateShaderModule(
inline ShaderModule::ShaderModule(const std::vector<uint32_t>& 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
@@ -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;
+7 -10
View File
@@ -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;
+5 -5
View File
@@ -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
+31 -19
View File
@@ -18,13 +18,29 @@ StructuredBuffer<uint> 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;
}
+6 -6
View File
@@ -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;
@@ -10,7 +10,7 @@ RWByteAddressBuffer counterBuffer : register(u4);
#ifdef EMIT_FROM_MESH
Buffer<uint> meshIndexBuffer : register(t0);
ByteAddressBuffer meshVertexBuffer_POS : register(t1);
Buffer<float4> 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;
}
@@ -15,9 +15,9 @@ RWStructuredBuffer<uint> aliveBuffer_NEW : register(u2);
RWStructuredBuffer<uint> deadBuffer : register(u3);
RWByteAddressBuffer counterBuffer : register(u4);
RWStructuredBuffer<float> distanceBuffer : register(u6);
RWByteAddressBuffer vertexBuffer_POS : register(u7);
RWByteAddressBuffer vertexBuffer_UVS : register(u8);
RWByteAddressBuffer vertexBuffer_COL : register(u9);
RWBuffer<float4> vertexBuffer_POS : register(u7);
RWBuffer<float4> vertexBuffer_UVS : register(u8);
RWBuffer<float4> vertexBuffer_COL : register(u9);
RWStructuredBuffer<uint> culledIndirectionBuffer : register(u10);
RWStructuredBuffer<uint> 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;
}
}
+89 -26
View File
@@ -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<uint> bindless_ib[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<uint> bindless_buffers_uint[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<uint2> bindless_buffers_uint2[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<uint3> bindless_buffers_uint3[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<uint4> bindless_buffers_uint4[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<float> bindless_buffers_float[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<float2> bindless_buffers_float2[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<float3> bindless_buffers_float3[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_UNIFORM_TEXEL_BUFFER)]] Buffer<float4> 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<uint4> bindless_textures_uint4[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] RWByteAddressBuffer bindless_rwbuffers[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer<uint> bindless_rwbuffers_uint[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer<uint2> bindless_rwbuffers_uint2[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer<uint3> bindless_rwbuffers_uint3[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer<uint4> bindless_rwbuffers_uint4[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer<float> bindless_rwbuffers_float[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer<float2> bindless_rwbuffers_float2[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer<float3> bindless_rwbuffers_float3[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_TEXEL_BUFFER)]] RWBuffer<float4> bindless_rwbuffers_float4[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE)]] RWTexture2D<float4> bindless_rwtextures[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE)]] RWTexture2DArray<float4> bindless_rwtextures2DArray[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_IMAGE)]] RWTexture3D<float4> 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<uint> bindless_ib[] : register(space4);
Buffer<uint> bindless_buffers_uint[] : register(space4);
Buffer<uint2> bindless_buffers_uint2[] : register(space5);
Buffer<uint3> bindless_buffers_uint3[] : register(space6);
Buffer<uint4> bindless_buffers_uint4[] : register(space7);
Buffer<float> bindless_buffers_float[] : register(space8);
Buffer<float2> bindless_buffers_float2[] : register(space9);
Buffer<float3> bindless_buffers_float3[] : register(space10);
Buffer<float4> 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<float> bindless_textures_float[] : register(space10);
Texture2D<float2> bindless_textures_float2[] : register(space11);
Texture2D<uint> bindless_textures_uint[] : register(space12);
Texture2D<uint4> 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<float> bindless_textures_float[] : register(space17);
Texture2D<float2> bindless_textures_float2[] : register(space18);
Texture2D<uint> bindless_textures_uint[] : register(space19);
Texture2D<uint4> bindless_textures_uint4[] : register(space20);
RWTexture2D<float4> bindless_rwtextures[] : register(space21);
RWByteAddressBuffer bindless_rwbuffers[] : register(space22);
RWBuffer<uint> bindless_rwbuffers_uint[] : register(space23);
RWBuffer<uint2> bindless_rwbuffers_uint2[] : register(space24);
RWBuffer<uint3> bindless_rwbuffers_uint3[] : register(space25);
RWBuffer<uint4> bindless_rwbuffers_uint4[] : register(space26);
RWBuffer<float> bindless_rwbuffers_float[] : register(space27);
RWBuffer<float2> bindless_rwbuffers_float2[] : register(space28);
RWBuffer<float3> bindless_rwbuffers_float3[] : register(space29);
RWBuffer<float4> bindless_rwbuffers_float4[] : register(space30);
RWTexture2DArray<float4> bindless_rwtextures2DArray[] : register(space31);
RWTexture3D<float4> bindless_rwtextures3D[] : register(space32);
RWTexture2D<uint> bindless_rwtextures_uint[] : register(space33);
RWTexture2D<float4> bindless_rwtextures[] : register(space14);
RWByteAddressBuffer bindless_rwbuffers[] : register(space15);
RWTexture2DArray<float4> bindless_rwtextures2DArray[] : register(space16);
RWTexture3D<float4> bindless_rwtextures3D[] : register(space17);
RWTexture2D<uint> bindless_rwtextures_uint[] : register(space18);
#endif // SPIRV
#include "ShaderInterop_Renderer.h"
#ifdef SPIRV
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] StructuredBuffer<ShaderMeshInstance> bindless_buffers_meshinstance[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] StructuredBuffer<ShaderGeometry> bindless_buffers_geometry[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] StructuredBuffer<ShaderMeshlet> bindless_buffers_meshlet[];
[[vk::binding(0, DESCRIPTOR_SET_BINDLESS_STORAGE_BUFFER)]] StructuredBuffer<ShaderMaterial> bindless_buffers_material[];
#else
StructuredBuffer<ShaderMeshInstance> bindless_buffers_meshinstance[] : register(space34);
StructuredBuffer<ShaderGeometry> bindless_buffers_geometry[] : register(space35);
StructuredBuffer<ShaderMeshlet> bindless_buffers_meshlet[] : register(space36);
StructuredBuffer<ShaderMaterial> 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<ShaderMeshInstance>(instanceIndex * sizeof(ShaderMeshInstance));
return bindless_buffers_meshinstance[GetScene().instancebuffer][instanceIndex];
}
inline ShaderGeometry load_geometry(uint geometryIndex)
{
return bindless_buffers[GetScene().geometrybuffer].Load<ShaderGeometry>(geometryIndex * sizeof(ShaderGeometry));
return bindless_buffers_geometry[GetScene().geometrybuffer][geometryIndex];
}
inline ShaderMeshlet load_meshlet(uint meshletIndex)
{
return bindless_buffers[GetScene().meshletbuffer].Load<ShaderMeshlet>(meshletIndex * sizeof(ShaderMeshlet));
return bindless_buffers_meshlet[GetScene().meshletbuffer][meshletIndex];
}
inline ShaderMaterial load_material(uint materialIndex)
{
return bindless_buffers[GetScene().materialbuffer].Load<ShaderMaterial>(materialIndex * sizeof(ShaderMaterial));
return bindless_buffers_material[GetScene().materialbuffer][materialIndex];
}
uint load_entitytile(uint tileIndex)
{
+4 -4
View File
@@ -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%
@@ -10,12 +10,12 @@ static const float3 HAIRPATCH[] = {
};
Buffer<uint> meshIndexBuffer : register(t0);
ByteAddressBuffer meshVertexBuffer_POS : register(t1);
Buffer<float4> meshVertexBuffer_POS : register(t1);
Buffer<float> meshVertexBuffer_length : register(t2);
RWStructuredBuffer<PatchSimulationData> simulationBuffer : register(u0);
RWByteAddressBuffer vertexBuffer_POS : register(u1);
RWByteAddressBuffer vertexBuffer_UVS : register(u2);
RWBuffer<float4> vertexBuffer_POS : register(u1);
RWBuffer<float4> vertexBuffer_UVS : register(u2);
RWBuffer<uint> culledIndexBuffer : register(u3);
RWStructuredBuffer<IndirectDrawArgsIndexedInstanced> 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;
}
}
}
+2 -2
View File
@@ -8,7 +8,7 @@ static const float2 BILLBOARD[] = {
float2(1, 1),
};
ByteAddressBuffer vb_pos_nor : register(t0);
Buffer<float4> 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;
+2 -2
View File
@@ -11,7 +11,7 @@ static const float3 BILLBOARD[] =
};
RWBuffer<uint> output_indices : register(u0);
RWByteAddressBuffer output_vertices_pos_nor : register(u1);
RWBuffer<float4> output_vertices_pos_nor : register(u1);
RWByteAddressBuffer output_impostor_data : register(u2);
RWStructuredBuffer<IndirectDrawArgsIndexedInstanced> 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)));
}
}
}
+12 -23
View File
@@ -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<float3>(vertexID * sizeof(uint4)), 1);
}
float3 GetNormal()
{
const uint normal_wind = bindless_buffers[GetMesh().vb_pos_nor_wind].Load<uint4>(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<uint4>(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
}
+32 -57
View File
@@ -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<float4> morphvb = bindless_buffers_float4[push.morphvb_index];
for (uint morph_index = 0; morph_index < push.morph_count; ++morph_index)
{
MorphTargetGPU morph = skinningbuffer.Load<MorphTargetGPU>(push.morph_offset + morph_index * sizeof(MorphTargetGPU));
if (morph.offset_pos != ~0u)
{
pos += unpack_half3(morphvb.Load<uint2>(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<uint2>(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<ShaderTransform>(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;
}
}
+55 -56
View File
@@ -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<uint> indexBuffer = bindless_ib[NonUniformResourceIndex(geometry.ib)];
Buffer<uint> 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<float4> 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<float4> 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<float4> 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<float4> 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<float2> 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<float4> 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<float4> 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);
+32 -16
View File
@@ -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)"
)]
+7 -8
View File
@@ -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;
+19 -8
View File
@@ -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)
{
+1
View File
@@ -85,6 +85,7 @@ namespace wi::graphics
wi::vector<VkDynamicState> pso_dynamicStates;
VkPipelineDynamicStateCreateInfo dynamicStateInfo = {};
VkPipelineDynamicStateCreateInfo dynamicStateInfo_MeshShader = {};
VkBuffer nullBuffer = VK_NULL_HANDLE;
VmaAllocation nullBufferAllocation = VK_NULL_HANDLE;
+6 -6
View File
@@ -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;
+1 -1
View File
@@ -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
{
+8 -8
View File
@@ -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;
+24 -15
View File
@@ -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);
}
+58 -60
View File
@@ -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;
};
};
+1 -1
View File
@@ -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);