refactor, optimize

This commit is contained in:
turanszkij
2019-08-22 19:36:55 +01:00
parent fadbd69433
commit 153ef72b98
14 changed files with 117 additions and 219 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
#define _SHADERINTEROP_BVH_H_
#include "ShaderInterop.h"
#define BVH_BUILDER_GROUPSIZE 64
static const uint BVH_BUILDER_GROUPSIZE = 64;
CBUFFER(BVHCB, CBSLOT_RENDERER_BVH)
{
+1 -1
View File
@@ -25,7 +25,7 @@ struct RaytracingStoredRay
uint3 direction_energy; // packed half3 direction | half3 energy
uint primitiveID;
float2 bary;
uint2 userdata; // vulkan complains about 16-byte padding here so might as well add userdata here and not pack barycentric coords
uint2 color; // packed rgba16
};
@@ -641,10 +641,6 @@
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
</FxCompile>
<FxCompile Include="raytrace_accumulateCS.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
</FxCompile>
<FxCompile Include="bvh_primitivesCS.hlsl">
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Compute</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">5.0</ShaderModel>
@@ -747,9 +747,6 @@
<FxCompile Include="bvh_primitivesCS.hlsl">
<Filter>CS</Filter>
</FxCompile>
<FxCompile Include="raytrace_accumulateCS.hlsl">
<Filter>CS</Filter>
</FxCompile>
<FxCompile Include="ssaoCS.hlsl">
<Filter>CS</Filter>
</FxCompile>
+15
View File
@@ -425,6 +425,21 @@ inline float4 unpack_rgba(in uint value)
return retVal;
}
inline uint2 pack_half3(in float3 value)
{
uint2 retVal = 0;
retVal.x = f32tof16(value.x) | (f32tof16(value.y) << 16);
retVal.y = f32tof16(value.z);
return retVal;
}
inline float3 unpack_half3(in uint2 value)
{
float3 retVal;
retVal.x = f16tof32(value.x);
retVal.y = f16tof32(value.x >> 16);
retVal.z = f16tof32(value.y);
return retVal;
}
inline uint2 pack_half4(in float4 value)
{
uint2 retVal = 0;
-19
View File
@@ -1,19 +0,0 @@
#include "globals.hlsli"
#include "ShaderInterop_Raytracing.h"
TEXTURE2D(sourceTexture, float4, TEXSLOT_ONDEMAND0);
RWTEXTURE2D(resultTexture, float4, 0);
[numthreads(RAYTRACING_ACCUMULATE_BLOCKSIZE, RAYTRACING_ACCUMULATE_BLOCKSIZE, 1)]
void main( uint3 DTid : SV_DispatchThreadID )
{
if (xTraceAccumulationFactor == 1.0f)
{
resultTexture[DTid.xy] = sourceTexture[DTid.xy]; // naturally the lerp solution below would be enough, but if the result texture is not initialized, it can contain nan that doesn't work well with lerp!
}
else
{
resultTexture[DTid.xy] = lerp(resultTexture[DTid.xy], sourceTexture[DTid.xy], xTraceAccumulationFactor);
}
}
+4 -6
View File
@@ -13,15 +13,13 @@ void main( uint3 DTid : SV_DispatchThreadID )
// Compute screen coordinates:
float2 uv = float2((DTid.xy + xTracePixelOffset) * xTraceResolution_rcp.xy * 2.0f - 1.0f) * float2(1, -1);
// Target pixel:
uint pixelID = flatten2D(DTid.xy, xTraceResolution.xy);
// Create starting ray:
Ray ray = CreateCameraRay(uv);
ray.pixelID = flatten2D(DTid.xy, xTraceResolution.xy);
// The launch writes each ray to the pixel location:
rayIndexBuffer[pixelID] = pixelID;
raySortBuffer[pixelID] = CreateRaySortCode(ray);
rayBuffer[pixelID] = CreateStoredRay(ray, pixelID);
rayIndexBuffer[ray.pixelID] = ray.pixelID;
raySortBuffer[ray.pixelID] = CreateRaySortCode(ray);
rayBuffer[ray.pixelID] = CreateStoredRay(ray);
}
}
+7 -10
View File
@@ -4,24 +4,23 @@
RAWBUFFER(counterBuffer_READ, TEXSLOT_ONDEMAND7);
STRUCTUREDBUFFER(rayIndexBuffer_READ, uint, TEXSLOT_ONDEMAND8);
STRUCTUREDBUFFER(rayBuffer_READ, RaytracingStoredRay, TEXSLOT_ONDEMAND9);
RWTEXTURE2D(resultTexture, float4, 0);
RWSTRUCTUREDBUFFER(rayBuffer, RaytracingStoredRay, 0);
[numthreads(RAYTRACING_TRACE_GROUPSIZE, 1, 1)]
void main( uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
{
// Initialize ray and pixel ID as non-contributing:
Ray ray = (Ray)0;
uint pixelID = 0xFFFFFFFF;
if (DTid.x < counterBuffer_READ.Load(0))
{
// Load the current ray:
LoadRay(rayBuffer_READ[rayIndexBuffer_READ[DTid.x]], ray, pixelID);
const uint rayIndex = rayIndexBuffer_READ[DTid.x];
LoadRay(rayBuffer[rayIndex], ray);
// Compute real pixel coords from flattened:
uint2 coords2D = unflatten2D(pixelID, xTraceResolution.xy);
uint2 coords2D = unflatten2D(ray.pixelID, xTraceResolution.xy);
// Compute screen coordinates:
float2 uv = float2((coords2D + xTracePixelOffset) * xTraceResolution_rcp.xy * 2.0f - 1.0f) * float2(1, -1);
@@ -219,11 +218,9 @@ void main( uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
}
}
finalResult *= ray.energy;
resultTexture[coords2D] += float4(max(0, finalResult), 0);
ray.color += max(0, ray.energy * finalResult);
// Store the current ray color:
rayBuffer[rayIndex].color = pack_half3(ray.color);
}
// This shader doesn't export any rays!
}
+21 -18
View File
@@ -46,15 +46,21 @@ void main( uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex )
// Initialize ray and pixel ID as non-contributing:
Ray ray = (Ray)0;
uint pixelID = 0xFFFFFFFF;
bool ray_active = false;
if (DTid.x < counterBuffer_READ.Load(0))
{
// Load the current ray:
LoadRay(rayBuffer_READ[rayIndexBuffer_READ[DTid.x]], ray, pixelID);
LoadRay(rayBuffer_READ[rayIndexBuffer_READ[DTid.x]], ray);
// Compute real pixel coords from flattened:
uint2 coords2D = unflatten2D(pixelID, xTraceResolution.xy);
uint2 coords2D = unflatten2D(ray.pixelID, xTraceResolution.xy);
// Pre-clear result texture for first bounce and first accumulation sample:
if (xTraceUserData.x == 1)
{
resultTexture[coords2D] = 0;
}
// Compute screen coordinates:
float2 uv = float2((coords2D + xTracePixelOffset) * xTraceResolution_rcp.xy * 2.0f - 1.0f) * float2(1, -1);
@@ -62,27 +68,25 @@ void main( uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex )
float seed = xTraceRandomSeed;
RayHit hit = TraceScene(ray);
float4 result = float4(max(0, ray.energy * Shade(ray, hit, seed, uv)), 0);
ShadeRay(ray, hit, seed, uv);
// Write pixel color:
if (xTraceUserData.x == 0) // first bounce clears texture
ray_active = any(ray.energy);
// If the ray is killed or last bounce, we write to accumulation texture:
if (!ray_active || xTraceUserData.y == 1)
{
resultTexture[coords2D] = result;
}
else // other bounces accumulate to texture
{
resultTexture[coords2D] += result;
resultTexture[coords2D] = lerp(resultTexture[coords2D], float4(ray.color, 1), xTraceAccumulationFactor);
}
#ifndef ADVANCED_ALLOCATION
if (any(ray.energy))
if (ray_active)
{
// Naive strategy to allocate active rays. Global memory atomics will be performed for every thread:
uint dest;
counterBuffer_WRITE.InterlockedAdd(0, 1, dest);
rayIndexBuffer_WRITE[dest] = dest;
raySortBuffer_WRITE[dest] = CreateRaySortCode(ray);
rayBuffer_WRITE[dest] = CreateStoredRay(ray, pixelID);
rayBuffer_WRITE[dest] = CreateStoredRay(ray);
}
#endif // ADVANCED_ALLOCATION
@@ -91,13 +95,12 @@ void main( uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex )
#ifdef ADVANCED_ALLOCATION
const bool active = any(ray.energy); // does this thread append?
const uint bucket = groupIndex / 32; // which bitfield bucket does this thread belong to?
const uint threadIndexInBucket = groupIndex % 32; // thread bit offset from bucket start
const uint threadMask = 1 << threadIndexInBucket; // thread bit mask in current bucket
// Count rays that are still active with a bitmask insertion:
if (active)
if (ray_active)
{
InterlockedOr(GroupActiveRayMask[bucket], threadMask);
}
@@ -118,7 +121,7 @@ void main( uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex )
GroupMemoryBarrierWithGroupSync();
// Finally, write all active rays into global memory:
if (active)
if (ray_active)
{
// Need to compute prefix-sum of just the active ray count before this thread
uint activePrefixSum = 0;
@@ -137,10 +140,10 @@ void main( uint3 DTid : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex )
activePrefixSum += countbits(GroupActiveRayMask[i] & prefixMask);
}
const uint dest = GroupRayWriteOffset + activePrefixSum - 1;
const uint dest = GroupRayWriteOffset + activePrefixSum - 1; // -1 because activePrefixSum includes current thread, but arrays start from 0!
rayIndexBuffer_WRITE[dest] = dest;
raySortBuffer_WRITE[dest] = CreateRaySortCode(ray);
rayBuffer_WRITE[dest] = CreateStoredRay(ray, pixelID); // -1 because activePrefixSum includes current thread, but arrays start from 0!
rayBuffer_WRITE[dest] = CreateStoredRay(ray);
}
#endif // ADVANCED_ALLOCATION
}
+17 -64
View File
@@ -17,27 +17,18 @@ static const float EPSILON = 0.0001f;
inline float3 trace_bias_position(in float3 P, in float3 N)
{
return P + N * EPSILON; // this is the original version
//return P + sign(N) * abs(P * 0.0000002); // this is from https://ndotl.wordpress.com/2018/08/29/baking-artifact-free-lightmaps/
}
//struct Sphere
//{
// float3 position;
// float radius;
// float3 albedo;
// float3 specular;
// float emission;
//};
struct Ray
{
uint pixelID;
float3 origin;
float3 direction;
float3 direction_rcp;
float3 energy;
uint primitiveID;
float2 bary;
float3 color;
inline void Update()
{
@@ -65,31 +56,28 @@ inline float CreateRaySortCode(in Ray ray)
//return (float)hash;
}
inline RaytracingStoredRay CreateStoredRay(in Ray ray, in uint pixelID)
inline RaytracingStoredRay CreateStoredRay(in Ray ray)
{
RaytracingStoredRay storedray;
storedray.origin = ray.origin;
storedray.pixelID = pixelID;
storedray.pixelID = ray.pixelID;
storedray.direction_energy = f32tof16(ray.direction) | (f32tof16(ray.energy) << 16);
storedray.primitiveID = ray.primitiveID;
//storedray.bary = f32tof16(ray.bary.x) | (f32tof16(ray.bary.y) << 16);
storedray.bary = ray.bary;
storedray.userdata = 0; // free to use for something
storedray.color = pack_half3(ray.color);
return storedray;
}
inline void LoadRay(in RaytracingStoredRay storedray, out Ray ray, out uint pixelID)
inline void LoadRay(in RaytracingStoredRay storedray, out Ray ray)
{
pixelID = storedray.pixelID;
ray.pixelID = storedray.pixelID;
ray.origin = storedray.origin;
ray.direction = asfloat(f16tof32(storedray.direction_energy));
ray.energy = asfloat(f16tof32(storedray.direction_energy >> 16));
ray.primitiveID = storedray.primitiveID;
ray.bary = storedray.bary;
//ray.bary.x = f16tof32(storedray.bary);
//ray.bary.y = f16tof32(storedray.bary >> 16);
ray.color = unpack_half3(storedray.color);
ray.Update();
}
@@ -99,8 +87,10 @@ inline Ray CreateRay(float3 origin, float3 direction)
ray.origin = origin;
ray.direction = direction;
ray.energy = float3(1, 1, 1);
ray.pixelID = 0xFFFFFFFF;
ray.primitiveID = 0xFFFFFFFF;
ray.bary = 0;
ray.color = 0;
ray.Update();
return ray;
}
@@ -148,37 +138,6 @@ inline RayHit CreateRayHit()
return hit;
}
//inline void IntersectGroundPlane(Ray ray, inout RayHit bestHit)
//{
// // Calculate distance along the ray where the ground plane is intersected
// float t = -ray.origin.y / ray.direction.y;
// if (t > 0 && t < bestHit.distance)
// {
// bestHit.distance = t;
// bestHit.position = ray.origin + t * ray.direction;
// bestHit.normal = float3(0.0f, 1.0f, 0.0f);
// }
//}
//
//inline void IntersectSphere(Ray ray, inout RayHit bestHit, Sphere sphere)
//{
// // Calculate distance along the ray where the sphere is intersected
// float3 d = ray.origin - sphere.position;
// float p1 = -dot(ray.direction, d);
// float p2sqr = p1 * p1 - dot(d, d) + sphere.radius * sphere.radius;
// if (p2sqr < 0)
// return;
// float p2 = sqrt(p2sqr);
// float t = p1 - p2 > 0 ? p1 - p2 : p1 + p2;
// if (t > 0 && t < bestHit.distance)
// {
// bestHit.distance = t;
// bestHit.position = ray.origin + t * ray.direction;
// bestHit.normal = normalize(bestHit.position - sphere.position);
// }
//}
struct TriangleData
{
float3 n0, n1, n2; // normals
@@ -314,11 +273,6 @@ inline bool IntersectNode(in Ray ray, in BVHNode box, in float primitive_best_di
}
inline bool IntersectNode(in Ray ray, in BVHNode box)
{
//if (ray.origin.x >= box.min.x && ray.origin.x <= box.max.x &&
// ray.origin.y >= box.min.y && ray.origin.y <= box.max.y &&
// ray.origin.z >= box.min.z && ray.origin.z <= box.max.z)
// return true;
float t[6];
t[0] = (box.min.x - ray.origin.x) * ray.direction_rcp.x;
t[1] = (box.max.x - ray.origin.x) * ray.direction_rcp.x;
@@ -519,7 +473,7 @@ inline uint TraceBVH(Ray ray)
// Also fill the final params of rayHit, such as normal, uv, materialIndex
// seed should be > 0
// pixel should be normalized uv coordinates of the ray start position (used to randomize)
inline float3 Shade(inout Ray ray, inout RayHit hit, inout float seed, in float2 pixel)
inline void ShadeRay(inout Ray ray, inout RayHit hit, inout float seed, in float2 pixel)
{
if (hit.distance < INFINITE_RAYHIT)
{
@@ -582,6 +536,8 @@ inline float3 Shade(inout Ray ray, inout RayHit hit, inout float seed, in float2
emissiveColor *= emissiveMap;
}
ray.color += max(0, ray.energy * emissiveColor.rgb * emissiveColor.a);
[branch]
if (material.uvset_normalMap >= 0)
{
@@ -594,8 +550,6 @@ inline float3 Shade(inout Ray ray, inout RayHit hit, inout float seed, in float2
hit.N = normalize(lerp(N, mul(normalMap, TBN), material.normalMapStrength));
}
// Calculate chances of reflection types:
const float refractChance = 1 - baseColor.a;
@@ -641,13 +595,9 @@ inline float3 Shade(inout Ray ray, inout RayHit hit, inout float seed, in float2
ray.primitiveID = hit.primitiveID;
ray.bary = hit.bary;
ray.Update();
return emissiveColor.rgb * emissiveColor.a;
}
else
{
// Erase the ray's energy - the sky doesn't reflect anything
ray.energy = 0.0f;
float3 envColor;
[branch]
@@ -660,7 +610,10 @@ inline float3 Shade(inout Ray ray, inout RayHit hit, inout float seed, in float2
{
envColor = GetDynamicSkyColor(ray.direction);
}
return envColor;
ray.color += max(0, ray.energy * envColor);
// Erase the ray's energy - the sky doesn't reflect anything
ray.energy = 0.0f;
}
}
+3 -4
View File
@@ -18,14 +18,13 @@ float4 main(Input input) : SV_TARGET
float seed = xTraceRandomSeed;
float3 direction = SampleHemisphere_uniform(N, seed, uv); // uniform because we care about only diffuse here
Ray ray = CreateRay(trace_bias_position(P, N), direction);
float3 finalResult = 0;
const uint bounces = xTraceUserData.x;
for (uint i = 0; (i < bounces) && any(ray.energy); ++i)
{
// Sample primary ray (scene materials, sky, etc):
RayHit hit = TraceScene(ray);
finalResult += ray.energy * Shade(ray, hit, seed, uv);
ShadeRay(ray, hit, seed, uv);
// We sample explicit lights for every bounce, but only diffuse part. Specular will not be baked here.
// Also, because we do it after the primary ray was bounced off, we only get the indirect part.
@@ -143,10 +142,10 @@ float4 main(Input input) : SV_TARGET
newRay.direction_rcp = rcp(newRay.direction);
newRay.energy = 0;
bool hit = TraceSceneANY(newRay, dist);
finalResult += ray.energy * (hit ? 0 : NdotL) * (lighting.direct.diffuse);
ray.color += ray.energy * (hit ? 0 : NdotL) * (lighting.direct.diffuse);
}
}
}
return max(0, float4(finalResult, xTraceAccumulationFactor));
return max(0, float4(ray.color, xTraceAccumulationFactor));
}
-1
View File
@@ -289,7 +289,6 @@ enum CSTYPES
CSTYPE_RAYTRACE_KICKJOBS,
CSTYPE_RAYTRACE_PRIMARY,
CSTYPE_RAYTRACE_LIGHTSAMPLING,
CSTYPE_RAYTRACE_ACCUMULATE,
CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT1,
CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT4,
CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_UNORM1,
+47 -87
View File
@@ -2149,7 +2149,6 @@ void LoadShaders()
computeShaders[CSTYPE_RAYTRACE_KICKJOBS] = static_cast<const ComputeShader*>(wiResourceManager::GetShaderManager().add(SHADERPATH + "raytrace_kickjobsCS.cso", wiResourceManager::COMPUTESHADER));
computeShaders[CSTYPE_RAYTRACE_PRIMARY] = static_cast<const ComputeShader*>(wiResourceManager::GetShaderManager().add(SHADERPATH + "raytrace_primaryCS.cso", wiResourceManager::COMPUTESHADER));
computeShaders[CSTYPE_RAYTRACE_LIGHTSAMPLING] = static_cast<const ComputeShader*>(wiResourceManager::GetShaderManager().add(SHADERPATH + "raytrace_lightsamplingCS.cso", wiResourceManager::COMPUTESHADER));
computeShaders[CSTYPE_RAYTRACE_ACCUMULATE] = static_cast<const ComputeShader*>(wiResourceManager::GetShaderManager().add(SHADERPATH + "raytrace_accumulateCS.cso", wiResourceManager::COMPUTESHADER));
computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT1] = static_cast<const ComputeShader*>(wiResourceManager::GetShaderManager().add(SHADERPATH + "blur_gaussian_float1CS.cso", wiResourceManager::COMPUTESHADER));
computeShaders[CSTYPE_POSTPROCESS_BLUR_GAUSSIAN_FLOAT4] = static_cast<const ComputeShader*>(wiResourceManager::GetShaderManager().add(SHADERPATH + "blur_gaussian_float4CS.cso", wiResourceManager::COMPUTESHADER));
@@ -7534,17 +7533,6 @@ void RayTraceScene(const RayBuffers* rayBuffers, const Texture2D* result, int ac
}
const TextureDesc& result_desc = result->GetDesc();
static TextureDesc temp_desc;
static Texture2D temp_texture;
if (temp_desc.Width < result_desc.Width || temp_desc.Height < result_desc.Height)
{
temp_desc.Width = std::max(temp_desc.Width, result_desc.Width);
temp_desc.Height = std::max(temp_desc.Height, result_desc.Height);
temp_desc.Format = FORMAT_R16G16B16A16_FLOAT;
temp_desc.BindFlags = BIND_UNORDERED_ACCESS | BIND_SHADER_RESOURCE;
device->CreateTexture2D(&temp_desc, nullptr, &temp_texture);
device->SetName(&temp_texture, "raytrace_temp_texture");
}
// Begin raytrace
@@ -7575,7 +7563,8 @@ void RayTraceScene(const RayBuffers* rayBuffers, const Texture2D* result, int ac
uint32_t __readBufferID = bounce % 2;
uint32_t __writeBufferID = (bounce + 1) % 2;
cb.xTraceUserData.x = bounce;
cb.xTraceUserData.x = (bounce == 0 && accumulation_sample == 0) ? 1 : 0; // pre-clear result texture?
cb.xTraceUserData.y = bounce == raytraceBounceCount ? 1 : 0; // accumulation step?
cb.xTraceRandomSeed = renderTime + (float)bounce;
device->UpdateBuffer(&constantBuffers[CBTYPE_RAYTRACE], &cb, cmd);
device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_RAYTRACE], CB_GETBINDSLOT(RaytracingCB), cmd);
@@ -7609,7 +7598,50 @@ void RayTraceScene(const RayBuffers* rayBuffers, const Texture2D* result, int ac
}
device->EventEnd(cmd);
// 1.) Compute Primary Trace (closest hit)
// Sorting and light sampling only after first bounce:
if (bounce > 0)
{
// Sort rays to achieve more coherency:
device->EventBegin("Ray Sorting", cmd);
wiGPUSortLib::Sort(rayBuffers->rayCapacity, rayBuffers->raySortBuffer, counterBuffer[__readBufferID], 0, rayBuffers->rayIndexBuffer[__readBufferID], cmd);
device->EventEnd(cmd);
// Light sampling (any hit)
{
device->EventBegin("Light Sampling Rays", cmd);
wiProfiler::range_id range;
if (bounce == 1)
{
range = wiProfiler::BeginRangeGPU("RayTrace - First Light Sampling", cmd);
}
device->BindComputeShader(computeShaders[CSTYPE_RAYTRACE_LIGHTSAMPLING], cmd);
const GPUResource* res[] = {
&counterBuffer[__readBufferID],
&rayBuffers->rayIndexBuffer[__readBufferID],
};
device->BindResources(CS, res, TEXSLOT_ONDEMAND7, ARRAYSIZE(res), cmd);
const GPUResource* uavs[] = {
&rayBuffers->rayBuffer[__readBufferID],
};
device->BindUAVs(CS, uavs, 0, ARRAYSIZE(uavs), cmd);
device->DispatchIndirect(&indirectBuffer, 0, cmd);
device->UAVBarrier(uavs, ARRAYSIZE(uavs), cmd);
device->UnbindUAVs(0, ARRAYSIZE(uavs), cmd);
if (bounce == 1)
{
wiProfiler::EndRange(range); // RayTrace - First Light Sampling
}
device->EventEnd(cmd);
}
}
// Compute Primary Trace (closest hit)
{
device->EventBegin("Primary Rays", cmd);
@@ -7636,7 +7668,7 @@ void RayTraceScene(const RayBuffers* rayBuffers, const Texture2D* result, int ac
&rayBuffers->rayIndexBuffer[__writeBufferID],
&rayBuffers->raySortBuffer,
&rayBuffers->rayBuffer[__writeBufferID],
&temp_texture,
result,
};
device->BindUAVs(CS, uavs, 0, ARRAYSIZE(uavs), cmd);
@@ -7651,80 +7683,8 @@ void RayTraceScene(const RayBuffers* rayBuffers, const Texture2D* result, int ac
}
device->EventEnd(cmd);
}
// Primary trace has written new alive ray buffer, so light sampling will use that:
std::swap(__readBufferID, __writeBufferID);
// 2.) Sort rays to achieve more coherency:
device->EventBegin("Ray Sorting", cmd);
wiGPUSortLib::Sort(rayBuffers->rayCapacity, rayBuffers->raySortBuffer, counterBuffer[__readBufferID], 0, rayBuffers->rayIndexBuffer[__readBufferID], cmd);
device->EventEnd(cmd);
// 3.) Light sampling (any hit) <- only after first bounce has occured
{
device->EventBegin("Light Sampling Rays", cmd);
wiProfiler::range_id range;
if (bounce == 1)
{
range = wiProfiler::BeginRangeGPU("RayTrace - First Light Sampling", cmd);
}
device->BindComputeShader(computeShaders[CSTYPE_RAYTRACE_LIGHTSAMPLING], cmd);
const GPUResource* res[] = {
&counterBuffer[__readBufferID],
&rayBuffers->rayIndexBuffer[__readBufferID],
&rayBuffers->rayBuffer[__readBufferID],
};
device->BindResources(CS, res, TEXSLOT_ONDEMAND7, ARRAYSIZE(res), cmd);
const GPUResource* uavs[] = {
&temp_texture,
};
device->BindUAVs(CS, uavs, 0, ARRAYSIZE(uavs), cmd);
device->DispatchIndirect(&indirectBuffer, 0, cmd);
device->UAVBarrier(uavs, ARRAYSIZE(uavs), cmd);
device->UnbindUAVs(0, ARRAYSIZE(uavs), cmd);
if (bounce == 1)
{
wiProfiler::EndRange(range); // RayTrace - First Light Sampling
}
device->EventEnd(cmd);
}
}
device->EventBegin("Accumulate", cmd);
{
device->BindComputeShader(computeShaders[CSTYPE_RAYTRACE_ACCUMULATE], cmd);
device->BindConstantBuffer(CS, &constantBuffers[CBTYPE_RAYTRACE], CB_GETBINDSLOT(RaytracingCB), cmd);
const GPUResource* res[] = {
&temp_texture
};
device->BindResources(CS, res, TEXSLOT_ONDEMAND0, ARRAYSIZE(res), cmd);
const GPUResource* uavs[] = {
result,
};
device->BindUAVs(CS, uavs, 0, ARRAYSIZE(uavs), cmd);
device->Dispatch(
(result_desc.Width + RAYTRACING_ACCUMULATE_BLOCKSIZE - 1) / RAYTRACING_ACCUMULATE_BLOCKSIZE,
(result_desc.Height + RAYTRACING_ACCUMULATE_BLOCKSIZE - 1) / RAYTRACING_ACCUMULATE_BLOCKSIZE,
1,
cmd);
device->UAVBarrier(uavs, ARRAYSIZE(uavs), cmd);
device->UnbindUAVs(0, ARRAYSIZE(uavs), cmd);
}
device->EventEnd(cmd);
wiProfiler::EndRange(range); // RayTrace - ALL
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wiVersion
// minor features, major updates
const int minor = 28;
// minor bug fixes, alterations, refactors, updates
const int revision = 10;
const int revision = 11;
long GetVersion()