diff --git a/gprt/gprt.cpp b/gprt/gprt.cpp index 643e93a..3a1e3ac 100644 --- a/gprt/gprt.cpp +++ b/gprt/gprt.cpp @@ -8531,7 +8531,7 @@ gprtGeomSetParameters(GPRTGeom _geometry, void *parameters, int deviceID) { void gprtGeomTypeRasterize(GPRTContext _context, GPRTGeomType _geomType, uint32_t numGeometry, GPRTGeom *_geometry, - uint32_t rasterType, uint32_t *instanceCounts) { + uint32_t rasterType, uint32_t *instanceCounts, size_t pushConstantsSize, void* pushConstants) { LOG_API_CALL(); Context *context = (Context *) _context; @@ -8592,6 +8592,12 @@ gprtGeomTypeRasterize(GPRTContext _context, GPRTGeomType _geomType, uint32_t num err = vkBeginCommandBuffer(context->graphicsCommandBuffer, &cmdBufInfo); + if (pushConstantsSize > 0) { + if (pushConstantsSize > 128) LOG_ERROR("Push constants size exceeds maximum 128 byte limit!"); + vkCmdPushConstants(context->graphicsCommandBuffer, geometryType->raster[rasterType].pipelineLayout, + VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, pushConstantsSize, pushConstants); + } + // Transition our attachments into optimal attachment formats geometryType->raster[rasterType].colorAttachment->setImageLayout( context->graphicsCommandBuffer, geometryType->raster[rasterType].colorAttachment->image, @@ -9861,19 +9867,19 @@ gprtBuildShaderBindingTable(GPRTContext _context, GPRTBuildSBTFlags flags) { } GPRT_API void -gprtRayGenLaunch1D(GPRTContext _context, GPRTRayGen _rayGen, uint32_t dims_x) { +gprtRayGenLaunch1D(GPRTContext _context, GPRTRayGen _rayGen, uint32_t dims_x, size_t pushConstantsSize, void* pushConstants) { LOG_API_CALL(); - gprtRayGenLaunch2D(_context, _rayGen, dims_x, 1); + gprtRayGenLaunch2D(_context, _rayGen, dims_x, 1, pushConstantsSize, pushConstants); } GPRT_API void -gprtRayGenLaunch2D(GPRTContext _context, GPRTRayGen _rayGen, uint32_t dims_x, uint32_t dims_y) { +gprtRayGenLaunch2D(GPRTContext _context, GPRTRayGen _rayGen, uint32_t dims_x, uint32_t dims_y, size_t pushConstantsSize, void* pushConstants) { LOG_API_CALL(); - gprtRayGenLaunch3D(_context, _rayGen, dims_x, dims_y, 1); + gprtRayGenLaunch3D(_context, _rayGen, dims_x, dims_y, 1, pushConstantsSize, pushConstants); } GPRT_API void -gprtRayGenLaunch3D(GPRTContext _context, GPRTRayGen _rayGen, uint32_t dims_x, uint32_t dims_y, uint32_t dims_z) { +gprtRayGenLaunch3D(GPRTContext _context, GPRTRayGen _rayGen, uint32_t dims_x, uint32_t dims_y, uint32_t dims_z, size_t pushConstantsSize, void* pushConstants) { LOG_API_CALL(); assert(_rayGen); @@ -9900,14 +9906,14 @@ gprtRayGenLaunch3D(GPRTContext _context, GPRTRayGen _rayGen, uint32_t dims_x, ui vkCmdBindPipeline(context->graphicsCommandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, context->raytracingPipeline); - struct PushConstants { - uint64_t pad[16] = {requestedFeatures.numRayTypes, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - } pushConstants; - vkCmdPushConstants(context->graphicsCommandBuffer, context->raytracingPipelineLayout, - VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR | - VK_SHADER_STAGE_INTERSECTION_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR | - VK_SHADER_STAGE_RAYGEN_BIT_KHR, - 0, sizeof(PushConstants), &pushConstants); + if (pushConstantsSize > 0) { + if (pushConstantsSize > 128) LOG_ERROR("Push constants size exceeds maximum 128 byte limit!"); + vkCmdPushConstants(context->graphicsCommandBuffer, context->raytracingPipelineLayout, + VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR | + VK_SHADER_STAGE_INTERSECTION_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR | + VK_SHADER_STAGE_RAYGEN_BIT_KHR, + 0, pushConstantsSize, pushConstants); + } auto getBufferDeviceAddress = [](VkDevice device, VkBuffer buffer) -> uint64_t { VkBufferDeviceAddressInfoKHR bufferDeviceAI{}; @@ -10000,7 +10006,7 @@ gprtRayGenLaunch3D(GPRTContext _context, GPRTRayGen _rayGen, uint32_t dims_x, ui } void -gprtComputeLaunch(GPRTContext _context, GPRTCompute _compute, uint32_t dims_x, uint32_t dims_y, uint32_t dims_z) { +gprtComputeLaunch(GPRTContext _context, GPRTCompute _compute, uint32_t dims_x, uint32_t dims_y, uint32_t dims_z, size_t pushConstantsSize, void* pushConstants) { assert(_compute); Context *context = (Context *) _context; @@ -10054,11 +10060,11 @@ gprtComputeLaunch(GPRTContext _context, GPRTCompute _compute, uint32_t dims_x, u std::to_string(context->deviceProperties.limits.maxComputeWorkGroupCount[2]) + ")\n"); } - struct PushConstants { - uint64_t pad[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - } pushConstants; - vkCmdPushConstants(context->graphicsCommandBuffer, compute->pipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, - sizeof(PushConstants), &pushConstants); + if (pushConstantsSize > 0) { + if (pushConstantsSize > 128) LOG_ERROR("Push constants size exceeds maximum 128 byte limit!"); + vkCmdPushConstants(context->graphicsCommandBuffer, compute->pipelineLayout, + VK_SHADER_STAGE_COMPUTE_BIT, 0, pushConstantsSize, pushConstants); + } vkCmdDispatch(context->graphicsCommandBuffer, dims_x, dims_y, dims_z); @@ -10090,21 +10096,21 @@ gprtComputeLaunch(GPRTContext _context, GPRTCompute _compute, uint32_t dims_x, u } GPRT_API void -gprtComputeLaunch1D(GPRTContext _context, GPRTCompute _compute, uint32_t dims_x) { +gprtComputeLaunch1D(GPRTContext _context, GPRTCompute _compute, uint32_t dims_x, size_t pushConstantsSize, void* pushConstants) { LOG_API_CALL(); - gprtComputeLaunch(_context, _compute, dims_x, 1, 1); + gprtComputeLaunch(_context, _compute, dims_x, 1, 1, pushConstantsSize, pushConstants); } GPRT_API void -gprtComputeLaunch2D(GPRTContext _context, GPRTCompute _compute, uint32_t dims_x, uint32_t dims_y) { +gprtComputeLaunch2D(GPRTContext _context, GPRTCompute _compute, uint32_t dims_x, uint32_t dims_y, size_t pushConstantsSize, void* pushConstants) { LOG_API_CALL(); - gprtComputeLaunch(_context, _compute, dims_x, dims_y, 1); + gprtComputeLaunch(_context, _compute, dims_x, dims_y, 1, pushConstantsSize, pushConstants); } GPRT_API void -gprtComputeLaunch3D(GPRTContext _context, GPRTCompute _compute, uint32_t dims_x, uint32_t dims_y, uint32_t dims_z) { +gprtComputeLaunch3D(GPRTContext _context, GPRTCompute _compute, uint32_t dims_x, uint32_t dims_y, uint32_t dims_z, size_t pushConstantsSize, void* pushConstants) { LOG_API_CALL(); - gprtComputeLaunch(_context, _compute, dims_x, dims_y, dims_z); + gprtComputeLaunch(_context, _compute, dims_x, dims_y, dims_z, pushConstantsSize, pushConstants); } GPRT_API void diff --git a/gprt/gprt_host.h b/gprt/gprt_host.h index 5972e4e..a132bc5 100644 --- a/gprt/gprt_host.h +++ b/gprt/gprt_host.h @@ -335,7 +335,8 @@ gprtTrianglesSetIndices(GPRTGeomOf triangles, GPRTBufferOf indices, uint for the given AABB geometry. This _has_ to be set before the accel(s) that this geom is used in get built. */ GPRT_API void gprtAABBsSetPositions(GPRTGeom aabbs, GPRTBuffer positions, uint32_t count, - uint32_t stride GPRT_IF_CPP(= 2 * sizeof(float3)), uint32_t offset GPRT_IF_CPP(= 0)); + uint32_t stride GPRT_IF_CPP(= 2 * sizeof(float3)), + uint32_t offset GPRT_IF_CPP(= 0)); template void @@ -1198,16 +1199,41 @@ gprtGeomTypeSetRasterAttachments(GPRTGeomTypeOf type, int rasterType, GPRTTe (GPRTTexture) depthAttachment); } +/** + * @brief Rasterize a list of GPRT geometry. (Currently assuming all geometry are GPRT_TRIANGLES) + * + * @param context The GPRT context used to rasterize the triangles + * @param geomType The geometry type to fetch raster programs from + * @param numGeometry The number of GPRTGeoms to rasterize + * @param geometry A pointer to a list of GPRT geometry, to be rasterized in the order given + * @param rasterType Controls which rasterization programs to use. Analogous to "Ray Type", in + * that it indexes into the shader binding table. + * @param instanceCounts How many instances of each geometry in the "geometry" list to rasterize. + * Useful for rasterizing the same geometry in many different locations. If null pointer, this parameter is ignored. + * Otherwise, we expect a list of length "numGeometry" + * @param pushConstantsSize The size of the push constants structure to upload to the device. + * If 0, no push constants are updated. Currently limited to 128 bytes or less. + * @param pushConstants A pointer to a structure of push constants to upload to the device. +*/ void gprtGeomTypeRasterize(GPRTContext context, GPRTGeomType geomType, uint32_t numGeometry, GPRTGeom *geometry, - uint32_t rasterType = 0, uint32_t *instanceCounts = nullptr); + uint32_t rasterType, uint32_t *instanceCounts, + size_t pushConstantsSize GPRT_IF_CPP(= 0), + void *pushConstants GPRT_IF_CPP(= 0)); -template +template void -gprtGeomTypeRasterize(GPRTContext context, GPRTGeomTypeOf geomType, uint32_t numGeometry, GPRTGeomOf *geometry, - uint32_t rayType = 0, uint32_t *instanceCounts = nullptr) { +gprtGeomTypeRasterize(GPRTContext context, GPRTGeomTypeOf geomType, uint32_t numGeometry, GPRTGeomOf *geometry, + uint32_t rayType, uint32_t *instanceCounts) { gprtGeomTypeRasterize(context, (GPRTGeomType) geomType, numGeometry, (GPRTGeom *) geometry, rayType, instanceCounts); } +template +void +gprtGeomTypeRasterize(GPRTContext context, GPRTGeomTypeOf geomType, uint32_t numGeometry, GPRTGeomOf *geometry, + uint32_t rayType, uint32_t *instanceCounts, PushConstantsType pc) { + gprtGeomTypeRasterize(context, (GPRTGeomType) geomType, numGeometry, (GPRTGeom *) geometry, rayType, instanceCounts, sizeof(PushConstantsType), &pc); +} + /** * @brief Creates a sampler object for use in sampling textures. Behavior below * defines how texture.SampleLevel and texture.SampleGrad operate. The "sampled @@ -1593,9 +1619,9 @@ GPRT_API void gprtBufferTextureCopy(GPRTContext context, GPRTBuffer buffer, GPRT template void gprtBufferTextureCopy(GPRTContext context, GPRTBufferOf buffer, GPRTTextureOf texture, uint32_t bufferOffset, - uint32_t bufferRowLength, uint32_t bufferImageHeight, uint32_t imageOffsetX, uint32_t imageOffsetY, - uint32_t imageOffsetZ, uint32_t imageExtentX, uint32_t imageExtentY, uint32_t imageExtentZ, - int srcDeviceID GPRT_IF_CPP(= 0), int dstDeviceID GPRT_IF_CPP(= 0)) { + uint32_t bufferRowLength, uint32_t bufferImageHeight, uint32_t imageOffsetX, + uint32_t imageOffsetY, uint32_t imageOffsetZ, uint32_t imageExtentX, uint32_t imageExtentY, + uint32_t imageExtentZ, int srcDeviceID GPRT_IF_CPP(= 0), int dstDeviceID GPRT_IF_CPP(= 0)) { gprtBufferTextureCopy(context, (GPRTBuffer) buffer, (GPRTTexture) texture, bufferOffset, bufferRowLength, bufferImageHeight, imageOffsetX, imageOffsetY, imageOffsetZ, imageExtentX, imageExtentY, imageExtentZ, srcDeviceID, dstDeviceID); @@ -1702,59 +1728,113 @@ gprtBufferSaveImage(GPRTBufferOf buffer, uint32_t width, uint32_t height, con gprtBufferSaveImage((GPRTBuffer) buffer, width, height, imageName); } -GPRT_API void gprtRayGenLaunch1D(GPRTContext context, GPRTRayGen rayGen, uint32_t dims_x); +GPRT_API void gprtRayGenLaunch1D(GPRTContext context, GPRTRayGen rayGen, uint32_t dims_x, + size_t pushConstantsSize GPRT_IF_CPP(= 0), void *pushConstants GPRT_IF_CPP(= 0)); -template +template void -gprtRayGenLaunch1D(GPRTContext context, GPRTRayGenOf rayGen, uint32_t dims_x) { +gprtRayGenLaunch1D(GPRTContext context, GPRTRayGenOf rayGen, uint32_t dims_x) { gprtRayGenLaunch1D(context, (GPRTRayGen) rayGen, dims_x); } +template +void +gprtRayGenLaunch1D(GPRTContext context, GPRTRayGenOf rayGen, uint32_t dims_x, PushConstantsType pushConstants) { + static_assert(sizeof(PushConstantsType) <= 128, "Current GPRT push constant size limited to 128 bytes or less"); + gprtRayGenLaunch1D(context, (GPRTRayGen) rayGen, dims_x, sizeof(PushConstantsType), &pushConstants); +} + /*! Executes a ray tracing pipeline with the given raygen program. This call will block until the raygen program returns. */ -GPRT_API void gprtRayGenLaunch2D(GPRTContext context, GPRTRayGen rayGen, uint32_t dims_x, uint32_t dims_y); +GPRT_API void gprtRayGenLaunch2D(GPRTContext context, GPRTRayGen rayGen, uint32_t dims_x, uint32_t dims_y, + size_t pushConstantsSize GPRT_IF_CPP(= 0), void *pushConstants GPRT_IF_CPP(= 0)); -template +template void -gprtRayGenLaunch2D(GPRTContext context, GPRTRayGenOf rayGen, uint32_t dims_x, uint32_t dims_y) { +gprtRayGenLaunch2D(GPRTContext context, GPRTRayGenOf rayGen, uint32_t dims_x, uint32_t dims_y) { gprtRayGenLaunch2D(context, (GPRTRayGen) rayGen, dims_x, dims_y); } +template +void +gprtRayGenLaunch2D(GPRTContext context, GPRTRayGenOf rayGen, uint32_t dims_x, uint32_t dims_y, PushConstantsType pushConstants) { + static_assert(sizeof(PushConstantsType) <= 128, "Current GPRT push constant size limited to 128 bytes or less"); + gprtRayGenLaunch2D(context, (GPRTRayGen) rayGen, dims_x, dims_y, sizeof(PushConstantsType), &pushConstants); +} + /*! 3D-launch variant of \see gprtRayGenLaunch2D */ -GPRT_API void gprtRayGenLaunch3D(GPRTContext context, GPRTRayGen rayGen, uint32_t dims_x, uint32_t dims_y, uint32_t dims_z); +GPRT_API void gprtRayGenLaunch3D(GPRTContext context, GPRTRayGen rayGen, uint32_t dims_x, uint32_t dims_y, + uint32_t dims_z, size_t pushConstantsSize GPRT_IF_CPP(= 0), + void *pushConstants GPRT_IF_CPP(= 0)); -template +template void -gprtRayGenLaunch3D(GPRTContext context, GPRTRayGenOf rayGen, uint32_t dims_x, uint32_t dims_y, uint32_t dims_z) { +gprtRayGenLaunch3D(GPRTContext context, GPRTRayGenOf rayGen, uint32_t dims_x, uint32_t dims_y, uint32_t dims_z) { gprtRayGenLaunch3D(context, (GPRTRayGen) rayGen, dims_x, dims_y, dims_z); } -GPRT_API void gprtComputeLaunch1D(GPRTContext context, GPRTCompute compute, uint32_t x_workgroups); +template +void +gprtRayGenLaunch3D(GPRTContext context, GPRTRayGenOf rayGen, uint32_t dims_x, uint32_t dims_y, uint32_t dims_z, PushConstantsType pushConstants) { + static_assert(sizeof(PushConstantsType) <= 128, "Current GPRT push constant size limited to 128 bytes or less"); + gprtRayGenLaunch3D(context, (GPRTRayGen) rayGen, dims_x, dims_y, dims_z, sizeof(PushConstantsType), &pushConstants); +} -template +GPRT_API void gprtComputeLaunch1D(GPRTContext context, GPRTCompute compute, uint32_t x_workgroups, + size_t pushConstantsSize GPRT_IF_CPP(= 0), + void *pushConstants GPRT_IF_CPP(= 0)); + +template void -gprtComputeLaunch1D(GPRTContext context, GPRTComputeOf compute, uint32_t x_workgroups) { +gprtComputeLaunch1D(GPRTContext context, GPRTComputeOf compute, uint32_t x_workgroups) { gprtComputeLaunch1D(context, (GPRTCompute) compute, x_workgroups); } -GPRT_API void gprtComputeLaunch2D(GPRTContext context, GPRTCompute compute, uint32_t x_workgroups, uint32_t y_workgroups); +template +void +gprtComputeLaunch1D(GPRTContext context, GPRTComputeOf compute, uint32_t x_workgroups, PushConstantsType pushConstants) { + static_assert(sizeof(PushConstantsType) <= 128, "Current GPRT push constant size limited to 128 bytes or less"); + gprtComputeLaunch1D(context, (GPRTCompute) compute, x_workgroups, sizeof(PushConstantsType), &pushConstants); +} -template +GPRT_API void gprtComputeLaunch2D(GPRTContext context, GPRTCompute compute, uint32_t x_workgroups, + uint32_t y_workgroups, + size_t pushConstantsSize GPRT_IF_CPP(= 0), + void *pushConstants GPRT_IF_CPP(= 0)); + +template void -gprtComputeLaunch2D(GPRTContext context, GPRTComputeOf compute, uint32_t x_workgroups, uint32_t y_workgroups) { +gprtComputeLaunch2D(GPRTContext context, GPRTComputeOf compute, uint32_t x_workgroups, uint32_t y_workgroups) { gprtComputeLaunch2D(context, (GPRTCompute) compute, x_workgroups, y_workgroups); } -GPRT_API void gprtComputeLaunch3D(GPRTContext context, GPRTCompute compute, uint32_t x_workgroups, uint32_t y_workgroups, - uint32_t z_workgroups); +template +void +gprtComputeLaunch2D(GPRTContext context, GPRTComputeOf compute, uint32_t x_workgroups, uint32_t y_workgroups, PushConstantsType pushConstants) { + static_assert(sizeof(PushConstantsType) <= 128, "Current GPRT push constant size limited to 128 bytes or less"); + gprtComputeLaunch2D(context, (GPRTCompute) compute, x_workgroups, y_workgroups, sizeof(PushConstantsType), &pushConstants); +} -template +GPRT_API void gprtComputeLaunch3D(GPRTContext context, GPRTCompute compute, uint32_t x_workgroups, + uint32_t y_workgroups, uint32_t z_workgroups, + size_t pushConstantsSize GPRT_IF_CPP(= 0), + void *pushConstants GPRT_IF_CPP(= 0)); + +template void -gprtComputeLaunch3D(GPRTContext context, GPRTComputeOf compute, uint32_t x_workgroups, uint32_t y_workgroups, +gprtComputeLaunch3D(GPRTContext context, GPRTComputeOf compute, uint32_t x_workgroups, uint32_t y_workgroups, uint32_t z_workgroups) { gprtComputeLaunch3D(context, (GPRTCompute) compute, x_workgroups, y_workgroups, z_workgroups); } +template +void +gprtComputeLaunch3D(GPRTContext context, GPRTComputeOf compute, uint32_t x_workgroups, uint32_t y_workgroups, + uint32_t z_workgroups, PushConstantsType pushConstants) { + static_assert(sizeof(PushConstantsType) <= 128, "Current GPRT push constant size limited to 128 bytes or less"); + gprtComputeLaunch3D(context, (GPRTCompute) compute, x_workgroups, y_workgroups, z_workgroups, sizeof(PushConstantsType), &pushConstants); +} + GPRT_API void gprtBeginProfile(GPRTContext context); // returned results are in milliseconds diff --git a/samples/s01-singleTriangle/deviceCode.hlsl b/samples/s01-singleTriangle/deviceCode.hlsl index 82e1acf..8b17db5 100644 --- a/samples/s01-singleTriangle/deviceCode.hlsl +++ b/samples/s01-singleTriangle/deviceCode.hlsl @@ -22,6 +22,8 @@ #include "sharedCode.h" +[[vk::push_constant]] PushConstants pc; + struct [raypayload] Payload { float3 color : read(caller) : write(closesthit, miss); }; @@ -40,9 +42,9 @@ GPRT_RAYGEN_PROGRAM(simpleRayGen, (RayGenData, record)) { float2 screen = (float2(pixelID) + float2(.5f, .5f)) / float2(fbSize); RayDesc rayDesc; - rayDesc.Origin = record.camera.pos; + rayDesc.Origin = pc.camera.pos; rayDesc.Direction = - normalize(record.camera.dir_00 + screen.x * record.camera.dir_du + screen.y * record.camera.dir_dv); + normalize(pc.camera.dir_00 + screen.x * pc.camera.dir_du + screen.y * pc.camera.dir_dv); rayDesc.TMin = 0.001; rayDesc.TMax = 10000.0; RaytracingAccelerationStructure world = gprt::getAccelHandle(record.world); diff --git a/samples/s01-singleTriangle/hostCode.cpp b/samples/s01-singleTriangle/hostCode.cpp index c9974ce..1bca519 100644 --- a/samples/s01-singleTriangle/hostCode.cpp +++ b/samples/s01-singleTriangle/hostCode.cpp @@ -160,6 +160,10 @@ main(int ac, char **av) { LOG("launching ..."); + // Structure of parameters that change each frame. We can edit these + // without rebuilding the shader binding table. + PushConstants pc; + bool firstFrame = true; double xpos = 0.f, ypos = 0.f; double lastxpos, lastypos; @@ -209,18 +213,14 @@ main(int ac, char **av) { camera_d00 -= 0.5f * camera_ddv; // ----------- set variables ---------------------------- - RayGenData *raygenData = gprtRayGenGetParameters(rayGen); - raygenData->camera.pos = camera_pos; - raygenData->camera.dir_00 = camera_d00; - raygenData->camera.dir_du = camera_ddu; - raygenData->camera.dir_dv = camera_ddv; - - // Use this to upload all set parameters to our ray tracing device - gprtBuildShaderBindingTable(context, GPRT_SBT_RAYGEN); + pc.camera.pos = camera_pos; + pc.camera.dir_00 = camera_d00; + pc.camera.dir_du = camera_ddu; + pc.camera.dir_dv = camera_ddv; } // Calls the GPU raygen kernel function - gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y); + gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y, pc); // If a window exists, presents the framebuffer here to that window gprtBufferPresent(context, frameBuffer); diff --git a/samples/s01-singleTriangle/sharedCode.h b/samples/s01-singleTriangle/sharedCode.h index 73ed36a..72cb649 100644 --- a/samples/s01-singleTriangle/sharedCode.h +++ b/samples/s01-singleTriangle/sharedCode.h @@ -31,15 +31,7 @@ struct TrianglesGeomData { struct RayGenData { alignas(16) gprt::Buffer frameBuffer; - alignas(16) gprt::Accel world; - - struct { - alignas(16) float3 pos; - alignas(16) float3 dir_00; - alignas(16) float3 dir_du; - alignas(16) float3 dir_dv; - } camera; }; /* variables for the miss program */ @@ -47,3 +39,14 @@ struct MissProgData { alignas(16) float3 color0; alignas(16) float3 color1; }; + +/* A small structure of constants that can change every frame without rebuilding the + shader binding table. (must be 128 bytes or less) */ +struct PushConstants { + struct { + alignas(16) float3 pos; + alignas(16) float3 dir_00; + alignas(16) float3 dir_du; + alignas(16) float3 dir_dv; + } camera; +}; \ No newline at end of file diff --git a/samples/s02-instances/deviceCode.hlsl b/samples/s02-instances/deviceCode.hlsl index 964ed37..35b77ee 100644 --- a/samples/s02-instances/deviceCode.hlsl +++ b/samples/s02-instances/deviceCode.hlsl @@ -22,6 +22,8 @@ #include "sharedCode.h" +[[vk::push_constant]] PushConstants pc; + struct [raypayload] Payload { float3 color : read(caller) : write(closesthit, miss); }; @@ -35,9 +37,9 @@ GPRT_RAYGEN_PROGRAM(simpleRayGen, (RayGenData, record)) { float2 screen = (float2(pixelID) + float2(.5f, .5f)) / float2(fbSize); RayDesc rayDesc; - rayDesc.Origin = record.camera.pos; + rayDesc.Origin = pc.camera.pos; rayDesc.Direction = - normalize(record.camera.dir_00 + screen.x * record.camera.dir_du + screen.y * record.camera.dir_dv); + normalize(pc.camera.dir_00 + screen.x * pc.camera.dir_du + screen.y * pc.camera.dir_dv); rayDesc.TMin = 0.001; rayDesc.TMax = 10000.0; RaytracingAccelerationStructure world = gprt::getAccelHandle(record.world); diff --git a/samples/s02-instances/hostCode.cpp b/samples/s02-instances/hostCode.cpp index 5661d54..8445d6b 100644 --- a/samples/s02-instances/hostCode.cpp +++ b/samples/s02-instances/hostCode.cpp @@ -167,6 +167,10 @@ main(int ac, char **av) { // now that everything is ready: launch it .... // ################################################################## + // Structure of parameters that change each frame. We can edit these + // without rebuilding the shader binding table. + PushConstants pc; + LOG("launching ..."); bool firstFrame = true; @@ -209,27 +213,17 @@ main(int ac, char **av) { lookFrom = ((mul(rotationMatrixY, (position - pivot))) + pivot).xyz(); // ----------- compute variable values ------------------ - float3 camera_pos = lookFrom; - float3 camera_d00 = normalize(lookAt - lookFrom); + pc.camera.pos = lookFrom; + pc.camera.dir_00 = normalize(lookAt - lookFrom); float aspect = float(fbSize.x) / float(fbSize.y); - float3 camera_ddu = cosFovy * aspect * normalize(cross(camera_d00, lookUp)); - float3 camera_ddv = cosFovy * normalize(cross(camera_ddu, camera_d00)); - camera_d00 -= 0.5f * camera_ddu; - camera_d00 -= 0.5f * camera_ddv; - - // ----------- set variables ---------------------------- - RayGenData *raygenData = gprtRayGenGetParameters(rayGen); - raygenData->camera.pos = camera_pos; - raygenData->camera.dir_00 = camera_d00; - raygenData->camera.dir_du = camera_ddu; - raygenData->camera.dir_dv = camera_ddv; - - // Use this to upload all set parameters to our ray tracing device - gprtBuildShaderBindingTable(context, GPRT_SBT_RAYGEN); + pc.camera.dir_du = cosFovy * aspect * normalize(cross(pc.camera.dir_00, lookUp)); + pc.camera.dir_dv = cosFovy * normalize(cross(pc.camera.dir_du, pc.camera.dir_00)); + pc.camera.dir_00 -= 0.5f * pc.camera.dir_du; + pc.camera.dir_00 -= 0.5f * pc.camera.dir_dv; } // Calls the GPU raygen kernel function - gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y); + gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y, pc); // If a window exists, presents the framebuffer here to that window gprtBufferPresent(context, frameBuffer); diff --git a/samples/s02-instances/sharedCode.h b/samples/s02-instances/sharedCode.h index be17b1b..ef73e99 100644 --- a/samples/s02-instances/sharedCode.h +++ b/samples/s02-instances/sharedCode.h @@ -34,19 +34,21 @@ struct TrianglesGeomData { struct RayGenData { alignas(16) gprt::Buffer frameBuffer; - alignas(16) gprt::Accel world; +}; + +/* variables for the miss program */ +struct MissProgData { + alignas(16) float3 color0; + alignas(16) float3 color1; +}; +/* Constants that change each frame */ +struct PushConstants { struct { alignas(16) float3 pos; alignas(16) float3 dir_00; alignas(16) float3 dir_du; alignas(16) float3 dir_dv; } camera; -}; - -/* variables for the miss program */ -struct MissProgData { - alignas(16) float3 color0; - alignas(16) float3 color1; }; \ No newline at end of file diff --git a/samples/s03-singleAABB/deviceCode.hlsl b/samples/s03-singleAABB/deviceCode.hlsl index f514c06..c2537c1 100644 --- a/samples/s03-singleAABB/deviceCode.hlsl +++ b/samples/s03-singleAABB/deviceCode.hlsl @@ -22,6 +22,8 @@ #include "sharedCode.h" +[[vk::push_constant]] PushConstants pc; + struct [raypayload] Payload { float3 color : read(caller) : write(closesthit, miss); }; @@ -35,9 +37,9 @@ GPRT_RAYGEN_PROGRAM(simpleRayGen, (RayGenData, record)) { float2 screen = (float2(pixelID) + float2(.5f, .5f)) / float2(fbSize); RayDesc rayDesc; - rayDesc.Origin = record.camera.pos; + rayDesc.Origin = pc.camera.pos; rayDesc.Direction = - normalize(record.camera.dir_00 + screen.x * record.camera.dir_du + screen.y * record.camera.dir_dv); + normalize(pc.camera.dir_00 + screen.x * pc.camera.dir_du + screen.y * pc.camera.dir_dv); rayDesc.TMin = 0.0; rayDesc.TMax = 10000.0; RaytracingAccelerationStructure world = gprt::getAccelHandle(record.world); diff --git a/samples/s03-singleAABB/hostCode.cpp b/samples/s03-singleAABB/hostCode.cpp index f460a23..3498be9 100644 --- a/samples/s03-singleAABB/hostCode.cpp +++ b/samples/s03-singleAABB/hostCode.cpp @@ -132,6 +132,10 @@ main(int ac, char **av) { LOG("launching ..."); + // Structure of parameters that change each frame. We can edit these + // without rebuilding the shader binding table. + PushConstants pc; + bool firstFrame = true; double xpos = 0.f, ypos = 0.f; double lastxpos, lastypos; @@ -172,27 +176,17 @@ main(int ac, char **av) { lookFrom = ((mul(rotationMatrixY, (position - pivot))) + pivot).xyz(); // ----------- compute variable values ------------------ - float3 camera_pos = lookFrom; - float3 camera_d00 = normalize(lookAt - lookFrom); + pc.camera.pos = lookFrom; + pc.camera.dir_00 = normalize(lookAt - lookFrom); float aspect = float(fbSize.x) / float(fbSize.y); - float3 camera_ddu = cosFovy * aspect * normalize(cross(camera_d00, lookUp)); - float3 camera_ddv = cosFovy * normalize(cross(camera_ddu, camera_d00)); - camera_d00 -= 0.5f * camera_ddu; - camera_d00 -= 0.5f * camera_ddv; - - // ----------- set variables ---------------------------- - RayGenData *raygenData = gprtRayGenGetParameters(rayGen); - raygenData->camera.pos = camera_pos; - raygenData->camera.dir_00 = camera_d00; - raygenData->camera.dir_du = camera_ddu; - raygenData->camera.dir_dv = camera_ddv; - - // Use this to upload all set parameters to our ray tracing device - gprtBuildShaderBindingTable(context, GPRT_SBT_RAYGEN); + pc.camera.dir_du = cosFovy * aspect * normalize(cross(pc.camera.dir_00, lookUp)); + pc.camera.dir_dv = cosFovy * normalize(cross(pc.camera.dir_du, pc.camera.dir_00)); + pc.camera.dir_00 -= 0.5f * pc.camera.dir_du; + pc.camera.dir_00 -= 0.5f * pc.camera.dir_dv; } // Calls the GPU raygen kernel function - gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y); + gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y, pc); // If a window exists, presents the frame buffer here to that window gprtBufferPresent(context, frameBuffer); diff --git a/samples/s03-singleAABB/sharedCode.h b/samples/s03-singleAABB/sharedCode.h index 1ee5283..ad6637e 100644 --- a/samples/s03-singleAABB/sharedCode.h +++ b/samples/s03-singleAABB/sharedCode.h @@ -31,15 +31,7 @@ struct AABBGeomData { struct RayGenData { alignas(16) gprt::Buffer frameBuffer; - alignas(16) gprt::Accel world; - - struct { - alignas(16) float3 pos; - alignas(16) float3 dir_00; - alignas(16) float3 dir_du; - alignas(16) float3 dir_dv; - } camera; }; /* variables for the miss program */ @@ -47,3 +39,13 @@ struct MissProgData { alignas(16) float3 color0; alignas(16) float3 color1; }; + +/* Constants that change each frame */ +struct PushConstants { + struct { + alignas(16) float3 pos; + alignas(16) float3 dir_00; + alignas(16) float3 dir_du; + alignas(16) float3 dir_dv; + } camera; +}; \ No newline at end of file diff --git a/samples/s04-computeAABBs/deviceCode.hlsl b/samples/s04-computeAABBs/deviceCode.hlsl index 15a2f58..b099a50 100644 --- a/samples/s04-computeAABBs/deviceCode.hlsl +++ b/samples/s04-computeAABBs/deviceCode.hlsl @@ -22,6 +22,8 @@ #include "sharedCode.h" +[[vk::push_constant]] PushConstants pc; + struct [raypayload] Payload { float3 color : read(caller) : write(closesthit, miss); }; @@ -33,9 +35,9 @@ GPRT_RAYGEN_PROGRAM(simpleRayGen, (RayGenData, record)) { float2 screen = (float2(pixelID) + float2(.5f, .5f)) / float2(fbSize); RayDesc rayDesc; - rayDesc.Origin = record.camera.pos; + rayDesc.Origin = pc.camera.pos; rayDesc.Direction = - normalize(record.camera.dir_00 + screen.x * record.camera.dir_du + screen.y * record.camera.dir_dv); + normalize(pc.camera.dir_00 + screen.x * pc.camera.dir_du + screen.y * pc.camera.dir_dv); rayDesc.TMin = 0.0; rayDesc.TMax = 10000.0; RaytracingAccelerationStructure world = gprt::getAccelHandle(record.world); diff --git a/samples/s04-computeAABBs/hostCode.cpp b/samples/s04-computeAABBs/hostCode.cpp index 4eb91de..3cfbdd8 100644 --- a/samples/s04-computeAABBs/hostCode.cpp +++ b/samples/s04-computeAABBs/hostCode.cpp @@ -163,6 +163,10 @@ main(int ac, char **av) { LOG("launching ..."); + // Structure of parameters that change each frame. We can edit these + // without rebuilding the shader binding table. + PushConstants pc; + bool firstFrame = true; double xpos = 0.f, ypos = 0.f; double lastxpos, lastypos; @@ -203,27 +207,17 @@ main(int ac, char **av) { lookFrom = ((mul(rotationMatrixY, (position - pivot))) + pivot).xyz(); // ----------- compute variable values ------------------ - float3 camera_pos = lookFrom; - float3 camera_d00 = normalize(lookAt - lookFrom); + pc.camera.pos = lookFrom; + pc.camera.dir_00 = normalize(lookAt - lookFrom); float aspect = float(fbSize.x) / float(fbSize.y); - float3 camera_ddu = cosFovy * aspect * normalize(cross(camera_d00, lookUp)); - float3 camera_ddv = cosFovy * normalize(cross(camera_ddu, camera_d00)); - camera_d00 -= 0.5f * camera_ddu; - camera_d00 -= 0.5f * camera_ddv; - - // ----------- set variables ---------------------------- - RayGenData *raygenData = gprtRayGenGetParameters(rayGen); - raygenData->camera.pos = camera_pos; - raygenData->camera.dir_00 = camera_d00; - raygenData->camera.dir_du = camera_ddu; - raygenData->camera.dir_dv = camera_ddv; - - // Use this to upload all set parameters to our ray tracing device - gprtBuildShaderBindingTable(context, GPRT_SBT_RAYGEN); + pc.camera.dir_du = cosFovy * aspect * normalize(cross(pc.camera.dir_00, lookUp)); + pc.camera.dir_dv = cosFovy * normalize(cross(pc.camera.dir_du, pc.camera.dir_00)); + pc.camera.dir_00 -= 0.5f * pc.camera.dir_du; + pc.camera.dir_00 -= 0.5f * pc.camera.dir_dv; } // Calls the GPU raygen kernel function - gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y); + gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y, pc); // If a window exists, presents the framebuffer here to that window gprtBufferPresent(context, frameBuffer); diff --git a/samples/s04-computeAABBs/sharedCode.h b/samples/s04-computeAABBs/sharedCode.h index 9711b62..807f9f1 100644 --- a/samples/s04-computeAABBs/sharedCode.h +++ b/samples/s04-computeAABBs/sharedCode.h @@ -52,15 +52,7 @@ struct SphereGeomData { struct RayGenData { alignas(16) gprt::Buffer frameBuffer; - alignas(16) gprt::Accel world; - - struct { - alignas(16) float3 pos; - alignas(16) float3 dir_00; - alignas(16) float3 dir_du; - alignas(16) float3 dir_dv; - } camera; }; /* variables for the miss program */ @@ -68,3 +60,13 @@ struct MissProgData { alignas(16) float3 color0; alignas(16) float3 color1; }; + +/* Constants that change each frame */ +struct PushConstants { + struct { + alignas(16) float3 pos; + alignas(16) float3 dir_00; + alignas(16) float3 dir_du; + alignas(16) float3 dir_dv; + } camera; +}; \ No newline at end of file diff --git a/samples/s05-computeVertex/deviceCode.hlsl b/samples/s05-computeVertex/deviceCode.hlsl index 4401970..550e421 100644 --- a/samples/s05-computeVertex/deviceCode.hlsl +++ b/samples/s05-computeVertex/deviceCode.hlsl @@ -22,6 +22,8 @@ #include "sharedCode.h" +[[vk::push_constant]] PushConstants pc; + float3 getPos(float px, float py, float k, float width, float depth, float height, float now) { float x = lerp(-1.f, 1.f, px); @@ -34,7 +36,6 @@ getPos(float px, float py, float k, float width, float depth, float height, floa GPRT_COMPUTE_PROGRAM(Vertex, (TrianglesGeomData, record), (1, 1, 1)) { uint gridSize = record.gridSize; int TriID = DispatchThreadID.x; - float now = record.now; bool even = (TriID % 2) == 0; @@ -53,13 +54,13 @@ GPRT_COMPUTE_PROGRAM(Vertex, (TrianglesGeomData, record), (1, 1, 1)) { float k = 20.f; if (even) { - v0 = getPos(gx, gy, k, width, depth, height, now); - v1 = getPos(gx + dx, gy, k, width, depth, height, now); - v2 = getPos(gx + dx, gy + dy, k, width, depth, height, now); + v0 = getPos(gx, gy, k, width, depth, height, pc.now); + v1 = getPos(gx + dx, gy, k, width, depth, height, pc.now); + v2 = getPos(gx + dx, gy + dy, k, width, depth, height, pc.now); } else { - v0 = getPos(gx, gy, k, width, depth, height, now); - v1 = getPos(gx + dx, gy + dy, k, width, depth, height, now); - v2 = getPos(gx, gy + dy, k, width, depth, height, now); + v0 = getPos(gx, gy, k, width, depth, height, pc.now); + v1 = getPos(gx + dx, gy + dy, k, width, depth, height, pc.now); + v2 = getPos(gx, gy + dy, k, width, depth, height, pc.now); } gprt::store(record.index, TriID, index); @@ -78,9 +79,9 @@ GPRT_RAYGEN_PROGRAM(RayGen, (RayGenData, record)) { uint2 fbSize = DispatchRaysDimensions().xy; float2 screen = (float2(pixelID) + float2(.5f, .5f)) / float2(fbSize); RayDesc rayDesc; - rayDesc.Origin = record.camera.pos; + rayDesc.Origin = pc.camera.pos; rayDesc.Direction = - normalize(record.camera.dir_00 + screen.x * record.camera.dir_du + screen.y * record.camera.dir_dv); + normalize(pc.camera.dir_00 + screen.x * pc.camera.dir_du + screen.y * pc.camera.dir_dv); rayDesc.TMin = 0.0; rayDesc.TMax = 10000.0; RaytracingAccelerationStructure world = gprt::getAccelHandle(record.world); diff --git a/samples/s05-computeVertex/hostCode.cpp b/samples/s05-computeVertex/hostCode.cpp index 566185a..459a67d 100644 --- a/samples/s05-computeVertex/hostCode.cpp +++ b/samples/s05-computeVertex/hostCode.cpp @@ -65,6 +65,11 @@ main(int ac, char **av) { GPRTContext context = gprtContextCreate(nullptr, 1); GPRTModule module = gprtModuleCreate(context, s05_deviceCode); + // Structure of parameters that change each frame. We can edit these + // without rebuilding the shader binding table. + PushConstants pc; + pc.now = 0.f; + // ################################################################## // set up all the GPU kernels we want to run // ################################################################## @@ -113,21 +118,19 @@ main(int ac, char **av) { TrianglesGeomData *geomData = gprtGeomGetParameters(trianglesGeom); geomData->vertex = gprtBufferGetHandle(vertexBuffer); geomData->index = gprtBufferGetHandle(indexBuffer); - geomData->now = 0.f; geomData->gridSize = GRID_SIDE_LENGTH; // Parameters for our vertex program that'll animate our vertices TrianglesGeomData *vertexData = gprtComputeGetParameters(vertexProgram); vertexData->vertex = gprtBufferGetHandle(vertexBuffer); vertexData->index = gprtBufferGetHandle(indexBuffer); - vertexData->now = 0.f; vertexData->gridSize = GRID_SIDE_LENGTH; // Build the shader binding table to upload parameters to the device gprtBuildShaderBindingTable(context, GPRT_SBT_COMPUTE); // Now, compute triangles in parallel with a vertex compute shader - gprtComputeLaunch1D(context, vertexProgram, numTriangles); + gprtComputeLaunch1D(context, vertexProgram, numTriangles, pc); // Now that our vertex buffer and index buffer are filled, we can compute // our triangles acceleration structure. @@ -207,29 +210,18 @@ main(int ac, char **av) { lookFrom = ((mul(rotationMatrixY, (position - pivot))) + pivot).xyz(); // ----------- compute variable values ------------------ - float3 camera_pos = lookFrom; - float3 camera_d00 = normalize(lookAt - lookFrom); + pc.camera.pos = lookFrom; + pc.camera.dir_00 = normalize(lookAt - lookFrom); float aspect = float(fbSize.x) / float(fbSize.y); - float3 camera_ddu = cosFovy * aspect * normalize(cross(camera_d00, lookUp)); - float3 camera_ddv = cosFovy * normalize(cross(camera_ddu, camera_d00)); - camera_d00 -= 0.5f * camera_ddu; - camera_d00 -= 0.5f * camera_ddv; - - // ----------- set variables ---------------------------- - RayGenData *raygenData = (RayGenData *) gprtRayGenGetParameters(rayGen); - raygenData->camera.pos = camera_pos; - raygenData->camera.dir_00 = camera_d00; - raygenData->camera.dir_du = camera_ddu; - raygenData->camera.dir_dv = camera_ddv; - - // Use this to upload all set parameters to our ray tracing device - gprtBuildShaderBindingTable(context, GPRT_SBT_RAYGEN); + pc.camera.dir_du = cosFovy * aspect * normalize(cross(pc.camera.dir_00, lookUp)); + pc.camera.dir_dv = cosFovy * normalize(cross(pc.camera.dir_du, pc.camera.dir_00)); + pc.camera.dir_00 -= 0.5f * pc.camera.dir_du; + pc.camera.dir_00 -= 0.5f * pc.camera.dir_dv; } // update time to move primitives. then, rebuild accel. - vertexData->now = float(gprtGetTime(context)); - gprtBuildShaderBindingTable(context, GPRT_SBT_COMPUTE); - gprtComputeLaunch1D(context, vertexProgram, numTriangles); + pc.now = float(gprtGetTime(context)); + gprtComputeLaunch1D(context, vertexProgram, numTriangles, pc); // Now that the vertices have moved, we need to update our bottom level tree. // Note, updates should only be used when primitive counts are unchanged and @@ -241,7 +233,7 @@ main(int ac, char **av) { gprtAccelUpdate(context, world); // Calls the GPU raygen kernel function - gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y); + gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y, pc); // If a window exists, presents the framebuffer here to that window gprtBufferPresent(context, frameBuffer); diff --git a/samples/s05-computeVertex/sharedCode.h b/samples/s05-computeVertex/sharedCode.h index 5542f1e..e56f01f 100644 --- a/samples/s05-computeVertex/sharedCode.h +++ b/samples/s05-computeVertex/sharedCode.h @@ -27,27 +27,30 @@ struct TrianglesGeomData { alignas(16) gprt::Buffer index; /*! array/buffer of vertex positions */ alignas(16) gprt::Buffer vertex; - /*! the current time */ - alignas(4) float now; /*! the number of triangles along a row */ alignas(4) unsigned int gridSize; }; struct RayGenData { alignas(16) gprt::Buffer frameBuffer; - alignas(16) gprt::Accel world; +}; + +/* variables for the miss program */ +struct MissProgData { + alignas(16) float3 color0; + alignas(16) float3 color1; +}; +/* Constants that change each frame */ +struct PushConstants { struct { alignas(16) float3 pos; alignas(16) float3 dir_00; alignas(16) float3 dir_du; alignas(16) float3 dir_dv; } camera; -}; -/* variables for the miss program */ -struct MissProgData { - alignas(16) float3 color0; - alignas(16) float3 color1; -}; + /*! the current time */ + alignas(4) float now; +}; \ No newline at end of file diff --git a/samples/s06-computeTransform/deviceCode.hlsl b/samples/s06-computeTransform/deviceCode.hlsl index 321e4a2..12bfe46 100644 --- a/samples/s06-computeTransform/deviceCode.hlsl +++ b/samples/s06-computeTransform/deviceCode.hlsl @@ -22,6 +22,8 @@ #include "sharedCode.h" +[[vk::push_constant]] PushConstants pc; + GPRT_COMPUTE_PROGRAM(Transform, (TransformData, record), (1, 1, 1)) { int numTransforms = record.numTransforms; int length = sqrt(numTransforms); @@ -32,8 +34,6 @@ GPRT_COMPUTE_PROGRAM(Transform, (TransformData, record), (1, 1, 1)) { float px = float(xid) / float(length); float py = float(yid) / float(length); - float now = record.now; - float height = .1; float width = 4.0; float depth = 4.0; @@ -41,7 +41,7 @@ GPRT_COMPUTE_PROGRAM(Transform, (TransformData, record), (1, 1, 1)) { float x = lerp(-1.f, 1.f, px); float y = lerp(-1.f, 1.f, py); - float z = sin(now + k * x) * cos(now + k * y); + float z = sin(pc.now + k * x) * cos(pc.now + k * y); float zoffset = x + y; float4 transforma = float4(0.04, 0.0, 0.0, x * width); @@ -64,9 +64,9 @@ GPRT_RAYGEN_PROGRAM(RayGen, (RayGenData, record)) { uint2 fbSize = DispatchRaysDimensions().xy; float2 screen = (float2(pixelID) + float2(.5f, .5f)) / float2(fbSize); RayDesc rayDesc; - rayDesc.Origin = record.camera.pos; + rayDesc.Origin = pc.camera.pos; rayDesc.Direction = - normalize(record.camera.dir_00 + screen.x * record.camera.dir_du + screen.y * record.camera.dir_dv); + normalize(pc.camera.dir_00 + screen.x * pc.camera.dir_du + screen.y * pc.camera.dir_dv); rayDesc.TMin = 0.0; rayDesc.TMax = 10000.0; RaytracingAccelerationStructure world = gprt::getAccelHandle(record.world); diff --git a/samples/s06-computeTransform/hostCode.cpp b/samples/s06-computeTransform/hostCode.cpp index 90c65e8..10453e5 100644 --- a/samples/s06-computeTransform/hostCode.cpp +++ b/samples/s06-computeTransform/hostCode.cpp @@ -119,6 +119,11 @@ main(int ac, char **av) { GPRTContext context = gprtContextCreate(nullptr, 1); GPRTModule module = gprtModuleCreate(context, s06_deviceCode); + // Structure of parameters that change each frame. We can edit these + // without rebuilding the shader binding table. + PushConstants pc; + pc.now = 0.f; + // ################################################################## // set up all the GPU kernels we want to run // ################################################################## @@ -180,13 +185,12 @@ main(int ac, char **av) { TransformData *transformData = gprtComputeGetParameters(transformProgram); transformData->transforms = gprtBufferGetHandle(transformBuffer); transformData->numTransforms = numInstances; - transformData->now = 0.f; // Build the shader binding table to upload parameters to the device gprtBuildShaderBindingTable(context, GPRT_SBT_COMPUTE); // Now, compute transforms in parallel with a transform compute shader - gprtComputeLaunch1D(context, transformProgram, numInstances); + gprtComputeLaunch1D(context, transformProgram, numInstances, pc); // Now that the transforms are set, we can build our top level acceleration // structure @@ -256,33 +260,23 @@ main(int ac, char **av) { lookFrom = ((mul(rotationMatrixY, (position - pivot))) + pivot).xyz(); // ----------- compute variable values ------------------ - float3 camera_pos = lookFrom; - float3 camera_d00 = normalize(lookAt - lookFrom); + pc.camera.pos = lookFrom; + pc.camera.dir_00 = normalize(lookAt - lookFrom); float aspect = float(fbSize.x) / float(fbSize.y); - float3 camera_ddu = cosFovy * aspect * normalize(cross(camera_d00, lookUp)); - float3 camera_ddv = cosFovy * normalize(cross(camera_ddu, camera_d00)); - camera_d00 -= 0.5f * camera_ddu; - camera_d00 -= 0.5f * camera_ddv; - - // ----------- set variables ---------------------------- - RayGenData *raygenData = gprtRayGenGetParameters(rayGen); - raygenData->camera.pos = camera_pos; - raygenData->camera.dir_00 = camera_d00; - raygenData->camera.dir_du = camera_ddu; - raygenData->camera.dir_dv = camera_ddv; - - gprtBuildShaderBindingTable(context, GPRT_SBT_RAYGEN); + pc.camera.dir_du = cosFovy * aspect * normalize(cross(pc.camera.dir_00, lookUp)); + pc.camera.dir_dv = cosFovy * normalize(cross(pc.camera.dir_du, pc.camera.dir_00)); + pc.camera.dir_00 -= 0.5f * pc.camera.dir_du; + pc.camera.dir_00 -= 0.5f * pc.camera.dir_dv; } // update time to move instance transforms. Then, update only instance // accel. - transformData->now = float(gprtGetTime(context)); - gprtBuildShaderBindingTable(context, GPRT_SBT_COMPUTE); - gprtComputeLaunch1D(context, transformProgram, numInstances); + pc.now = float(gprtGetTime(context)); + gprtComputeLaunch1D(context, transformProgram, numInstances, pc); gprtAccelUpdate(context, world); // Now, trace rays - gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y); + gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y, pc); // If a window exists, presents the framebuffer here to that window gprtBufferPresent(context, frameBuffer); diff --git a/samples/s06-computeTransform/sharedCode.h b/samples/s06-computeTransform/sharedCode.h index 54d9ea5..7698ad6 100644 --- a/samples/s06-computeTransform/sharedCode.h +++ b/samples/s06-computeTransform/sharedCode.h @@ -27,8 +27,6 @@ struct TransformData { alignas(16) gprt::Buffer transforms; /*! the number of transforms stored in the buffer */ alignas(4) int numTransforms; - /*! the current time */ - alignas(4) float now; }; struct TrianglesGeomData { @@ -36,27 +34,30 @@ struct TrianglesGeomData { alignas(16) gprt::Buffer index; /*! array/buffer of vertex positions */ alignas(16) gprt::Buffer vertex; - /*! the current time */ - alignas(4) float now; /*! the number of triangles along a row */ alignas(4) unsigned int gridSize; }; struct RayGenData { alignas(16) gprt::Buffer frameBuffer; - alignas(16) gprt::Accel world; +}; + +/* variables for the miss program */ +struct MissProgData { + alignas(16) float3 color0; + alignas(16) float3 color1; +}; +/* Constants that change each frame */ +struct PushConstants { struct { alignas(16) float3 pos; alignas(16) float3 dir_00; alignas(16) float3 dir_du; alignas(16) float3 dir_dv; } camera; -}; -/* variables for the miss program */ -struct MissProgData { - alignas(16) float3 color0; - alignas(16) float3 color1; -}; + /*! the current time */ + alignas(4) float now; +}; \ No newline at end of file diff --git a/samples/s07-multipleGeometry/deviceCode.hlsl b/samples/s07-multipleGeometry/deviceCode.hlsl index 1997409..79fc83f 100644 --- a/samples/s07-multipleGeometry/deviceCode.hlsl +++ b/samples/s07-multipleGeometry/deviceCode.hlsl @@ -22,6 +22,8 @@ #include "sharedCode.h" +[[vk::push_constant]] PushConstants pc; + struct [raypayload] Payload { float3 color : read(caller) : write(closesthit, miss); }; @@ -34,9 +36,9 @@ GPRT_RAYGEN_PROGRAM(raygen, (RayGenData, record)) { // Generate ray RayDesc rayDesc; - rayDesc.Origin = record.camera.pos; + rayDesc.Origin = pc.camera.pos; rayDesc.Direction = - normalize(record.camera.dir_00 + screen.x * record.camera.dir_du + screen.y * record.camera.dir_dv); + normalize(pc.camera.dir_00 + screen.x * pc.camera.dir_du + screen.y * pc.camera.dir_dv); rayDesc.TMin = 0.0; rayDesc.TMax = 1e20f; diff --git a/samples/s07-multipleGeometry/hostCode.cpp b/samples/s07-multipleGeometry/hostCode.cpp index ab810ad..29e2a29 100644 --- a/samples/s07-multipleGeometry/hostCode.cpp +++ b/samples/s07-multipleGeometry/hostCode.cpp @@ -177,6 +177,10 @@ main(int ac, char **av) { LOG("launching ..."); + // Structure of parameters that change each frame. We can edit these + // without rebuilding the shader binding table. + PushConstants pc; + bool firstFrame = true; double xpos = 0.f, ypos = 0.f; double lastxpos, lastypos; @@ -217,26 +221,17 @@ main(int ac, char **av) { lookFrom = ((mul(rotationMatrixY, (position - pivot))) + pivot).xyz(); // ----------- compute variable values ------------------ - float3 camera_pos = lookFrom; - float3 camera_d00 = normalize(lookAt - lookFrom); + pc.camera.pos = lookFrom; + pc.camera.dir_00 = normalize(lookAt - lookFrom); float aspect = float(fbSize.x) / float(fbSize.y); - float3 camera_ddu = cosFovy * aspect * normalize(cross(camera_d00, lookUp)); - float3 camera_ddv = cosFovy * normalize(cross(camera_ddu, camera_d00)); - camera_d00 -= 0.5f * camera_ddu; - camera_d00 -= 0.5f * camera_ddv; - - // ----------- set variables ---------------------------- - RayGenData *raygenData = gprtRayGenGetParameters(rayGen); - raygenData->camera.pos = camera_pos; - raygenData->camera.dir_00 = camera_d00; - raygenData->camera.dir_du = camera_ddu; - raygenData->camera.dir_dv = camera_ddv; - - gprtBuildShaderBindingTable(context, GPRT_SBT_RAYGEN); + pc.camera.dir_du = cosFovy * aspect * normalize(cross(pc.camera.dir_00, lookUp)); + pc.camera.dir_dv = cosFovy * normalize(cross(pc.camera.dir_du, pc.camera.dir_00)); + pc.camera.dir_00 -= 0.5f * pc.camera.dir_du; + pc.camera.dir_00 -= 0.5f * pc.camera.dir_dv; } // Calls the GPU raygen kernel function - gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y); + gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y, pc); // If a window exists, presents the framebuffer here to that window gprtBufferPresent(context, frameBuffer); diff --git a/samples/s07-multipleGeometry/sharedCode.h b/samples/s07-multipleGeometry/sharedCode.h index b977d8d..f4cc968 100644 --- a/samples/s07-multipleGeometry/sharedCode.h +++ b/samples/s07-multipleGeometry/sharedCode.h @@ -36,15 +36,7 @@ struct TrianglesGeomData { struct RayGenData { alignas(16) gprt::Buffer frameBuffer; - alignas(16) gprt::Accel world; - - struct { - alignas(16) float3 pos; - alignas(16) float3 dir_00; - alignas(16) float3 dir_du; - alignas(16) float3 dir_dv; - } camera; }; /* variables for the miss program */ @@ -52,3 +44,13 @@ struct MissProgData { alignas(16) float3 color0; alignas(16) float3 color1; }; + +/* Constants that change each frame */ +struct PushConstants { + struct { + alignas(16) float3 pos; + alignas(16) float3 dir_00; + alignas(16) float3 dir_du; + alignas(16) float3 dir_dv; + } camera; +}; \ No newline at end of file diff --git a/samples/s08-singleTexture/deviceCode.hlsl b/samples/s08-singleTexture/deviceCode.hlsl index be66aa7..6ccb6e9 100644 --- a/samples/s08-singleTexture/deviceCode.hlsl +++ b/samples/s08-singleTexture/deviceCode.hlsl @@ -22,6 +22,8 @@ #include "sharedCode.h" +[[vk::push_constant]] PushConstants pc; + struct [raypayload] Payload { float spreadAngle : read(closesthit) : write(caller); float3 color : read(caller) : write(closesthit, miss); @@ -50,7 +52,7 @@ GPRT_COMPUTE_PROGRAM(Transform, (TransformData, record), (1, 1, 1)) { int transformY = transformID % 2; int numTransforms = record.numTransforms; - float angle = record.now; + float angle = pc.now; float3x3 aa = AngleAxis3x3(angle, float3(0.0, 1.0, 0.0)); float4 transforma = float4(aa[0], lerp(-5, 5, transformX / float((numTransforms / 2) - 1))); @@ -72,14 +74,14 @@ GPRT_RAYGEN_PROGRAM(raygen, (RayGenData, record)) { // Generate ray RayDesc rayDesc; - rayDesc.Origin = record.camera.pos; + rayDesc.Origin = pc.camera.pos; rayDesc.Direction = - normalize(record.camera.dir_00 + screen.x * record.camera.dir_du + screen.y * record.camera.dir_dv); + normalize(pc.camera.dir_00 + screen.x * pc.camera.dir_du + screen.y * pc.camera.dir_dv); rayDesc.TMin = 0.0; rayDesc.TMax = 1e20f; // compute the spreading angle of the ray to determine the sampling footprint - float phi = record.camera.fovy; + float phi = pc.camera.fovy; float H = dims.y; payload.spreadAngle = atan(2.f * tan(phi / 2.f) / H); @@ -141,7 +143,7 @@ GPRT_CLOSEST_HIT_PROGRAM(closesthit, (TrianglesGeomData, record), (Payload, payl float w, h; texture.GetDimensions(w, h); int levels = log2(max(w, h)); - color = texture.SampleLevel(sampler, TC, lerp(levels, 0, abs(sin(record.now)))); + color = texture.SampleLevel(sampler, TC, lerp(levels, 0, abs(sin(pc.now)))); } // For the 3rd and 4th textures, we want to zoom in to show the magnification filter. diff --git a/samples/s08-singleTexture/hostCode.cpp b/samples/s08-singleTexture/hostCode.cpp index 7095c76..ccc0c95 100644 --- a/samples/s08-singleTexture/hostCode.cpp +++ b/samples/s08-singleTexture/hostCode.cpp @@ -94,6 +94,8 @@ main(int ac, char **av) { gprtRequestWindow(fbSize.x, fbSize.y, "Int08 Single Texture"); GPRTContext context = gprtContextCreate(nullptr, 1); GPRTModule module = gprtModuleCreate(context, s08_deviceCode); + PushConstants pc; + pc.now = 0.f; // ################################################################## // set up all the GPU kernels we want to run @@ -164,7 +166,6 @@ main(int ac, char **av) { planeData->vertex = gprtBufferGetHandle(vertexBuffer); planeData->texcoord = gprtBufferGetHandle(texcoordBuffer); planeData->texture = gprtTextureGetHandle(texture); - planeData->now = 0.0; for (uint32_t i = 0; i < samplers.size(); ++i) { planeData->samplers[i] = gprtSamplerGetHandle(samplers[i]); } @@ -172,11 +173,10 @@ main(int ac, char **av) { GPRTBufferOf transformBuffer = gprtDeviceBufferCreate(context, samplers.size(), nullptr); TransformData *transformData = gprtComputeGetParameters(transformProgram); - transformData->now = 0.0; transformData->transforms = gprtBufferGetHandle(transformBuffer); transformData->numTransforms = (uint32_t)samplers.size(); gprtBuildShaderBindingTable(context, GPRT_SBT_COMPUTE); - gprtComputeLaunch1D(context, transformProgram, (uint32_t)samplers.size()); + gprtComputeLaunch1D(context, transformProgram, (uint32_t)samplers.size(), pc); GPRTAccel trianglesBLAS = gprtTrianglesAccelCreate(context, 1, &plane); @@ -247,38 +247,23 @@ main(int ac, char **av) { lookFrom = ((mul(rotationMatrixY, (position - pivot))) + pivot).xyz(); // ----------- compute variable values ------------------ - float3 camera_pos = lookFrom; - float3 camera_d00 = normalize(lookAt - lookFrom); + pc.camera.pos = lookFrom; + pc.camera.dir_00 = normalize(lookAt - lookFrom); float aspect = float(fbSize.x) / float(fbSize.y); - float3 camera_ddu = cosFovy * aspect * normalize(cross(camera_d00, lookUp)); - float3 camera_ddv = cosFovy * normalize(cross(camera_ddu, camera_d00)); - camera_d00 -= 0.5f * camera_ddu; - camera_d00 -= 0.5f * camera_ddv; - - // ----------- set variables ---------------------------- - RayGenData *raygenData = gprtRayGenGetParameters(rayGen); - raygenData->camera.pos = camera_pos; - raygenData->camera.dir_00 = camera_d00; - raygenData->camera.dir_du = camera_ddu; - raygenData->camera.dir_dv = camera_ddv; - raygenData->camera.fovy = cosFovy; - - gprtBuildShaderBindingTable(context, GPRT_SBT_RAYGEN); + pc.camera.dir_du = cosFovy * aspect * normalize(cross(pc.camera.dir_00, lookUp)); + pc.camera.dir_dv = cosFovy * normalize(cross(pc.camera.dir_du, pc.camera.dir_00)); + pc.camera.dir_00 -= 0.5f * pc.camera.dir_du; + pc.camera.dir_00 -= 0.5f * pc.camera.dir_dv; + pc.camera.fovy = cosFovy; } // Animate transforms - TransformData *transformData = gprtComputeGetParameters(transformProgram); - transformData->now = .5f * (float)gprtGetTime(context); - gprtBuildShaderBindingTable(context, GPRT_SBT_COMPUTE); - gprtComputeLaunch1D(context, transformProgram, instances.size()); + pc.now = .5f * (float)gprtGetTime(context); + gprtComputeLaunch1D(context, transformProgram, instances.size(), pc); gprtAccelUpdate(context, trianglesTLAS); - - TrianglesGeomData *planeMeshData = gprtGeomGetParameters(plane); - planeMeshData->now = (float)gprtGetTime(context); - gprtBuildShaderBindingTable(context, GPRT_SBT_GEOM); // Calls the GPU raygen kernel function - gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y); + gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y, pc); // If a window exists, presents the framebuffer here to that window gprtBufferPresent(context, frameBuffer); diff --git a/samples/s08-singleTexture/sharedCode.h b/samples/s08-singleTexture/sharedCode.h index 648c54c..8e3c985 100644 --- a/samples/s08-singleTexture/sharedCode.h +++ b/samples/s08-singleTexture/sharedCode.h @@ -28,8 +28,6 @@ struct TransformData { /*! array/buffer of instance transforms */ alignas(16) gprt::Buffer transforms; alignas(4) int numTransforms; - /*! the current time */ - alignas(4) float now; }; /* variables for the triangle mesh geometry */ @@ -44,16 +42,22 @@ struct TrianglesGeomData { alignas(16) gprt::Texture texture; /*! an array of texture samplers to use */ alignas(16) gprt::Sampler samplers[12]; - /*! the current time */ - alignas(8) float now; }; struct RayGenData { alignas(16) gprt::Accel world; alignas(16) gprt::Buffer framebuffer; - alignas(8) int2 fbSize; +}; +/* variables for the miss program */ +struct MissProgData { + alignas(16) float3 color0; + alignas(16) float3 color1; +}; + +/* Constants that change each frame */ +struct PushConstants { struct { alignas(16) float3 pos; alignas(16) float3 dir_00; @@ -61,10 +65,7 @@ struct RayGenData { alignas(16) float3 dir_dv; alignas(4) float fovy; } camera; -}; -/* variables for the miss program */ -struct MissProgData { - alignas(16) float3 color0; - alignas(16) float3 color1; -}; + /*! the current time */ + alignas(8) float now; +}; \ No newline at end of file diff --git a/samples/s09-visibilityMasks/deviceCode.hlsl b/samples/s09-visibilityMasks/deviceCode.hlsl index 57035b0..9c4c6f1 100644 --- a/samples/s09-visibilityMasks/deviceCode.hlsl +++ b/samples/s09-visibilityMasks/deviceCode.hlsl @@ -22,6 +22,8 @@ #include "sharedCode.h" +[[vk::push_constant]] PushConstants pc; + struct [raypayload] Payload { float4 color : read(caller) : write(closesthit, miss); float3 normal : read(caller) : write(closesthit, miss); @@ -43,9 +45,9 @@ GPRT_RAYGEN_PROGRAM(simpleRayGen, (RayGenData, record)) { float2 screen = (float2(pixelID) + float2(.5f, .5f)) / float2(fbSize); RayDesc rayDesc; - rayDesc.Origin = record.camera.pos; + rayDesc.Origin = pc.camera.pos; rayDesc.Direction = - normalize(record.camera.dir_00 + screen.x * record.camera.dir_du + screen.y * record.camera.dir_dv); + normalize(pc.camera.dir_00 + screen.x * pc.camera.dir_du + screen.y * pc.camera.dir_dv); rayDesc.TMin = 0.001; rayDesc.TMax = 10000.0; RaytracingAccelerationStructure world = gprt::getAccelHandle(record.world); @@ -99,7 +101,7 @@ GPRT_RAYGEN_PROGRAM(simpleRayGen, (RayGenData, record)) { // note, adding a normal offset to avoid self-intersections rayDesc.Origin = hitPos + .001f * normal; - rayDesc.Direction = normalize(record.lightPos); + rayDesc.Direction = normalize(pc.lightPos); // Trace our primary visibility ray TraceRay(world, // the tree @@ -117,7 +119,7 @@ GPRT_RAYGEN_PROGRAM(simpleRayGen, (RayGenData, record)) { // We hit the light if (payload.hitT == -1.f) { - litColor += color * max(dot(normal, rayDesc.Direction), 0.0f) * (1.f - ambient) * record.lightColor; + litColor += color * max(dot(normal, rayDesc.Direction), 0.0f) * (1.f - ambient) * pc.lightColor; } shadedColor = over(transparentColor, float4(litColor, 1.f)); diff --git a/samples/s09-visibilityMasks/hostCode.cpp b/samples/s09-visibilityMasks/hostCode.cpp index 38502db..bae292d 100644 --- a/samples/s09-visibilityMasks/hostCode.cpp +++ b/samples/s09-visibilityMasks/hostCode.cpp @@ -125,6 +125,8 @@ main(int ac, char **av) { GPRTContext context = gprtContextCreate(); GPRTModule module = gprtModuleCreate(context, s09_deviceCode); + PushConstants pc; + // ################################################################## // set up all the GPU kernels we want to run // ################################################################## @@ -146,10 +148,6 @@ main(int ac, char **av) { GPRTBufferOf frameBuffer = gprtDeviceBufferCreate(context, fbSize.x * fbSize.y); rayGenData->frameBuffer = gprtBufferGetHandle(frameBuffer); - // Here, we'll setup our initial light position and color - rayGenData->lightPos = lightPos; - rayGenData->lightColor = lightColor; - // Miss program checkerboard background colors MissProgData *missData = gprtMissGetParameters(miss); missData->color0 = float3(0.1f, 0.1f, 0.1f); @@ -250,6 +248,10 @@ main(int ac, char **av) { LOG("launching ..."); + // Here, we'll setup our initial light position and color + pc.lightPos = lightPos; + pc.lightColor = lightColor; + bool firstFrame = true; double xpos = 0.f, ypos = 0.f; double lastxpos, lastypos; @@ -290,30 +292,20 @@ main(int ac, char **av) { lookFrom = ((mul(rotationMatrixY, (position - pivot))) + pivot).xyz(); // ----------- compute variable values ------------------ - float3 camera_pos = lookFrom; - float3 camera_d00 = normalize(lookAt - lookFrom); + pc.camera.pos = lookFrom; + pc.camera.dir_00 = normalize(lookAt - lookFrom); float aspect = float(fbSize.x) / float(fbSize.y); - float3 camera_ddu = cosFovy * aspect * normalize(cross(camera_d00, lookUp)); - float3 camera_ddv = cosFovy * normalize(cross(camera_ddu, camera_d00)); - camera_d00 -= 0.5f * camera_ddu; - camera_d00 -= 0.5f * camera_ddv; - - // ----------- set variables ---------------------------- - RayGenData *raygenData = gprtRayGenGetParameters(rayGen); - raygenData->camera.pos = camera_pos; - raygenData->camera.dir_00 = camera_d00; - raygenData->camera.dir_du = camera_ddu; - raygenData->camera.dir_dv = camera_ddv; - - // Use this to upload all set parameters to our ray tracing device - gprtBuildShaderBindingTable(context, GPRT_SBT_RAYGEN); + pc.camera.dir_du = cosFovy * aspect * normalize(cross(pc.camera.dir_00, lookUp)); + pc.camera.dir_dv = cosFovy * normalize(cross(pc.camera.dir_du, pc.camera.dir_00)); + pc.camera.dir_00 -= 0.5f * pc.camera.dir_du; + pc.camera.dir_00 -= 0.5f * pc.camera.dir_dv; } - rayGenData->lightPos = float3(3.f * sin((float)gprtGetTime(context)), 3.f, 3.f * cos((float)gprtGetTime(context))); - gprtBuildShaderBindingTable(context, GPRT_SBT_RAYGEN); + pc.lightPos = float3(3.f * sin((float)gprtGetTime(context)), 3.f, 3.f * cos((float)gprtGetTime(context))); + pc.lightColor = lightColor; // Calls the GPU raygen kernel function - gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y); + gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y, pc); // If a window exists, presents the framebuffer here to that window gprtBufferPresent(context, frameBuffer); diff --git a/samples/s09-visibilityMasks/sharedCode.h b/samples/s09-visibilityMasks/sharedCode.h index 9f4d96a..289642b 100644 --- a/samples/s09-visibilityMasks/sharedCode.h +++ b/samples/s09-visibilityMasks/sharedCode.h @@ -33,9 +33,17 @@ struct TrianglesGeomData { struct RayGenData { alignas(16) gprt::Buffer frameBuffer; - alignas(16) gprt::Accel world; +}; + +/* variables for the miss program */ +struct MissProgData { + alignas(16) float3 color0; + alignas(16) float3 color1; +}; +/* Constants that change each frame */ +struct PushConstants { struct { alignas(16) float3 pos; alignas(16) float3 dir_00; @@ -45,10 +53,4 @@ struct RayGenData { alignas(16) float3 lightColor; alignas(16) float3 lightPos; -}; - -/* variables for the miss program */ -struct MissProgData { - alignas(16) float3 color0; - alignas(16) float3 color1; -}; +}; \ No newline at end of file diff --git a/samples/s10-rasterization/deviceCode.hlsl b/samples/s10-rasterization/deviceCode.hlsl index ff569dc..680e145 100644 --- a/samples/s10-rasterization/deviceCode.hlsl +++ b/samples/s10-rasterization/deviceCode.hlsl @@ -1,5 +1,7 @@ #include "sharedCode.h" +[[vk::push_constant]] PushConstants pc; + GPRT_VERTEX_PROGRAM(backgroundVertex, (BackgroundData, record)) { uint32_t vertexID = VertexIndex(); float3 position = gprt::load(record.vertex, vertexID); @@ -15,8 +17,8 @@ GPRT_PIXEL_PROGRAM(backgroundPixel, (BackgroundData, record)) { GPRT_VERTEX_PROGRAM(simpleVertex, (TrianglesGeomData, record)) { uint32_t vertexID = VertexIndex(); - float4x4 view = record.view; - float4x4 proj = record.proj; + float4x4 view = pc.view; + float4x4 proj = pc.proj; float4 position = float4(gprt::load(record.vertex, vertexID), 1.f); position = mul(view, position); position = mul(proj, position); diff --git a/samples/s10-rasterization/hostCode.cpp b/samples/s10-rasterization/hostCode.cpp index 4a48587..b2f01aa 100644 --- a/samples/s10-rasterization/hostCode.cpp +++ b/samples/s10-rasterization/hostCode.cpp @@ -154,6 +154,8 @@ main(int ac, char **av) { LOG("launching ..."); + PushConstants pc; + bool firstFrame = true; double xpos = 0.f, ypos = 0.f; double lastxpos, lastypos; @@ -194,24 +196,28 @@ main(int ac, char **av) { lookFrom = ((mul(rotationMatrixY, (position - pivot))) + pivot).xyz(); float aspect = float(fbSize.x) / float(fbSize.y); - float4x4 lookAtMatrix = lookat_matrix(position.xyz(), pivot.xyz(), lookUp); - float4x4 perspectiveMatrix = perspective_matrix(cosFovy, aspect, 0.1f, 1000.f); - - tridata->view = lookAtMatrix; - tridata->proj = perspectiveMatrix; - - gprtBuildShaderBindingTable(context, GPRT_SBT_RASTER); + pc.view = lookat_matrix(position.xyz(), pivot.xyz(), lookUp); + pc.proj = perspective_matrix(cosFovy, aspect, 0.1f, 1000.f); } gprtTextureClear(depthAttachment); gprtTextureClear(colorAttachment); std::vector> drawList1 = {bgGeom}; - gprtGeomTypeRasterize(context, backdropGeomType, drawList1.size(), drawList1.data()); + gprtGeomTypeRasterize(context, backdropGeomType, drawList1.size(), drawList1.data(), + 0, nullptr, pc); gprtTextureClear(depthAttachment); std::vector> drawList2 = {trianglesGeom}; - gprtGeomTypeRasterize(context, trianglesGeomType, drawList2.size(), drawList2.data()); + gprtGeomTypeRasterize(context, + /* Where to pull "raster" programs from */ + trianglesGeomType, + /* The objects we want to rasterize, and in the order to rasterize them in */ + drawList2.size(), drawList2.data(), + /* How many instances of each object we want to rasterize (will explore in a future sample)*/ + 0, nullptr, + /* Parameters to send to each program, without updating the shader binding table */ + pc); // If a window exists, presents the framebuffer here to that window gprtTexturePresent(context, colorAttachment); diff --git a/samples/s10-rasterization/sharedCode.h b/samples/s10-rasterization/sharedCode.h index 9b62188..c3841f4 100644 --- a/samples/s10-rasterization/sharedCode.h +++ b/samples/s10-rasterization/sharedCode.h @@ -28,9 +28,6 @@ struct TrianglesGeomData { alignas(16) gprt::Buffer index; // int3* alignas(16) gprt::Buffer vertex; // float3* alignas(16) gprt::Buffer color; // float3* - - alignas(16) float4x4 view; - alignas(16) float4x4 proj; }; /* variables for the geometry representing the background */ @@ -39,4 +36,10 @@ struct BackgroundData { alignas(16) gprt::Buffer vertex; // float3* alignas(16) float3 color0; alignas(16) float3 color1; +}; + +/* Constants that change each frame */ +struct PushConstants { + alignas(16) float4x4 view; + alignas(16) float4x4 proj; }; \ No newline at end of file diff --git a/samples/s11-imgui/deviceCode.hlsl b/samples/s11-imgui/deviceCode.hlsl index 99b1d69..f4b8e44 100644 --- a/samples/s11-imgui/deviceCode.hlsl +++ b/samples/s11-imgui/deviceCode.hlsl @@ -1,5 +1,7 @@ #include "sharedCode.h" +[[vk::push_constant]] PushConstants pc; + GPRT_VERTEX_PROGRAM(backgroundVertex, (BackgroundData, record)) { uint32_t vertexID = VertexIndex(); float3 position = gprt::load(record.vertex, vertexID); @@ -28,8 +30,8 @@ GPRT_PIXEL_PROGRAM(GUIPixel, (GUIData, record)) { GPRT_VERTEX_PROGRAM(simpleVertex, (TrianglesGeomData, record)) { uint32_t vertexID = VertexIndex(); - float4x4 view = record.view; - float4x4 proj = record.proj; + float4x4 view = pc.view; + float4x4 proj = pc.proj; float4 position = float4(gprt::load(record.vertex, vertexID), 1.f); position = mul(view, position); position = mul(proj, position); diff --git a/samples/s11-imgui/hostCode.cpp b/samples/s11-imgui/hostCode.cpp index 2bbd6c5..97b5262 100644 --- a/samples/s11-imgui/hostCode.cpp +++ b/samples/s11-imgui/hostCode.cpp @@ -191,6 +191,8 @@ main(int ac, char **av) { LOG("launching ..."); + PushConstants pc; + bool firstFrame = true; double xpos = 0.f, ypos = 0.f; double lastxpos, lastypos; @@ -234,13 +236,8 @@ main(int ac, char **av) { lookFrom = ((mul(rotationMatrixY, (position - pivot))) + pivot).xyz(); float aspect = float(fbSize.x) / float(fbSize.y); - float4x4 lookAtMatrix = lookat_matrix(position.xyz(), pivot.xyz(), lookUp); - float4x4 perspectiveMatrix = perspective_matrix(cosFovy, aspect, 0.1f, 1000.f); - - tridata->view = lookAtMatrix; - tridata->proj = perspectiveMatrix; - - gprtBuildShaderBindingTable(context, GPRT_SBT_RASTER); + pc.view = lookat_matrix(position.xyz(), pivot.xyz(), lookUp); + pc.proj = perspective_matrix(cosFovy, aspect, 0.1f, 1000.f); } // Draw our background and triangle @@ -248,11 +245,11 @@ main(int ac, char **av) { gprtTextureClear(colorAttachment); std::vector> drawList1 = {bgGeom}; - gprtGeomTypeRasterize(context, backdropGeomType, drawList1.size(), drawList1.data()); + gprtGeomTypeRasterize(context, backdropGeomType, drawList1.size(), drawList1.data(), 0, nullptr, pc); gprtTextureClear(depthAttachment); std::vector> drawList2 = {trianglesGeom}; - gprtGeomTypeRasterize(context, trianglesGeomType, drawList2.size(), drawList2.data()); + gprtGeomTypeRasterize(context, trianglesGeomType, drawList2.size(), drawList2.data(), 0, nullptr, pc); gprtTextureClear(depthAttachment); // Set our ImGui state @@ -268,7 +265,7 @@ main(int ac, char **av) { // Finally, composite the gui onto the screen. std::vector> drawList3 = {guiGeom}; - gprtGeomTypeRasterize(context, guiGeomType, drawList3.size(), drawList3.data()); + gprtGeomTypeRasterize(context, guiGeomType, drawList3.size(), drawList3.data(), 0, nullptr, pc); // If a window exists, presents the framebuffer here to that window gprtTexturePresent(context, colorAttachment); diff --git a/samples/s11-imgui/sharedCode.h b/samples/s11-imgui/sharedCode.h index 08655a9..b3bbcce 100644 --- a/samples/s11-imgui/sharedCode.h +++ b/samples/s11-imgui/sharedCode.h @@ -28,9 +28,6 @@ struct TrianglesGeomData { alignas(16) gprt::Buffer index; // int3* alignas(16) gprt::Buffer vertex; // float3* alignas(16) gprt::Buffer color; // float3* - - alignas(16) float4x4 view; - alignas(16) float4x4 proj; }; /* variables for the geometry representing the background */ @@ -47,4 +44,10 @@ struct GUIData { alignas(16) gprt::Buffer vertex; // float3* alignas(16) gprt::Texture texture; alignas(8) float2 resolution; +}; + +/* Constants that change each frame */ +struct PushConstants { + alignas(16) float4x4 view; + alignas(16) float4x4 proj; }; \ No newline at end of file diff --git a/samples/s12-swBVH/deviceCode.hlsl b/samples/s12-swBVH/deviceCode.hlsl index 2b33143..20357ac 100644 --- a/samples/s12-swBVH/deviceCode.hlsl +++ b/samples/s12-swBVH/deviceCode.hlsl @@ -24,6 +24,8 @@ #include "rng.h" +[[vk::push_constant]] PushConstants pc; + // A bounding box, I think. // https://iquilezles.org/articles/boxfunctions float2 iBox(float3 ro, float3 rd, float3 rad) @@ -476,13 +478,13 @@ GPRT_RAYGEN_PROGRAM(simpleRayGen, (RayGenData, record)) { uint2 pixelID = DispatchRaysIndex().xy; uint2 fbSize = DispatchRaysDimensions().xy; - LCGRand rng = get_rng(record.iFrame, pixelID, fbSize); + LCGRand rng = get_rng(pc.iFrame, pixelID, fbSize); // if (all(pixelID == uint2(fbSize / 2))) { // // printf("seed %d\n", seed); // } - // printf("ID %d %d Frame %d\n", pixelID.x, pixelID.y, record.iFrame); + // printf("ID %d %d Frame %d\n", pixelID.x, pixelID.y, pc.iFrame); LBVHData lbvh = record.lbvh; if (all(pixelID == (fbSize / 2))) lbvh.tmp = 1; @@ -490,16 +492,16 @@ GPRT_RAYGEN_PROGRAM(simpleRayGen, (RayGenData, record)) { float2 screen = (float2(pixelID) + float2(.5f, .5f)) / float2(fbSize); RayDesc rayDesc; - rayDesc.Origin = record.camera.pos; + rayDesc.Origin = pc.camera.pos; rayDesc.Direction = - normalize(record.camera.dir_00 + screen.x * record.camera.dir_du + screen.y * record.camera.dir_dv); + normalize(pc.camera.dir_00 + screen.x * pc.camera.dir_du + screen.y * pc.camera.dir_dv); rayDesc.TMin = 0.0; rayDesc.TMax = 10000.0; float2 fragCoord = pixelID; float2 iResolution = fbSize; - float cuttingPlane = record.cuttingPlane; + float cuttingPlane = pc.cuttingPlane; // render bool isInterior = false; @@ -517,7 +519,7 @@ GPRT_RAYGEN_PROGRAM(simpleRayGen, (RayGenData, record)) { col = pow(col, 0.4545); - int frame = record.iFrame; + int frame = pc.iFrame; const int fbOfs = pixelID.x + fbSize.x * pixelID.y; float4 prev = gprt::load(record.accumBuffer, fbOfs); float4 newCol = prev * (frame / (frame + 1.f)) + float4(col, 1.0f) * (1.f / (frame + 1.f)); diff --git a/samples/s12-swBVH/hostCode.cpp b/samples/s12-swBVH/hostCode.cpp index 15900bb..00b8659 100644 --- a/samples/s12-swBVH/hostCode.cpp +++ b/samples/s12-swBVH/hostCode.cpp @@ -298,8 +298,6 @@ main(int ac, char **av) { rayGenData->lbvh = lbvh.handle; - rayGenData->cuttingPlane = 0.f; - gprtBuildShaderBindingTable(context, GPRT_SBT_ALL); // ################################################################## @@ -308,6 +306,8 @@ main(int ac, char **av) { LOG("launching ..."); + PushConstants pc; + bool firstFrame = true; double xpos = 0.f, ypos = 0.f; double lastxpos, lastypos; @@ -350,38 +350,27 @@ main(int ac, char **av) { lookFrom = ((mul(rotationMatrixY, (position - pivot))) + pivot).xyz(); // ----------- compute variable values ------------------ - float3 camera_pos = lookFrom; - float3 camera_d00 = normalize(lookAt - lookFrom); + pc.camera.pos = lookFrom; + pc.camera.dir_00 = normalize(lookAt - lookFrom); float aspect = float(fbSize.x) / float(fbSize.y); - float3 camera_ddu = cosFovy * aspect * normalize(cross(camera_d00, lookUp)); - float3 camera_ddv = cosFovy * normalize(cross(camera_ddu, camera_d00)); - camera_d00 -= 0.5f * camera_ddu; - camera_d00 -= 0.5f * camera_ddv; - - // ----------- set variables ---------------------------- - RayGenData *raygenData = gprtRayGenGetParameters(rayGen); - raygenData->camera.pos = camera_pos; - raygenData->camera.dir_00 = camera_d00; - raygenData->camera.dir_du = camera_ddu; - raygenData->camera.dir_dv = camera_ddv; + pc.camera.dir_du = cosFovy * aspect * normalize(cross(pc.camera.dir_00, lookUp)); + pc.camera.dir_dv = cosFovy * normalize(cross(pc.camera.dir_du, pc.camera.dir_00)); + pc.camera.dir_00 -= 0.5f * pc.camera.dir_du; + pc.camera.dir_00 -= 0.5f * pc.camera.dir_dv; iFrame = 0; } if (lstate == GPRT_PRESS || firstFrame) { - RayGenData *raygenData = gprtRayGenGetParameters(rayGen); - raygenData->cuttingPlane = float(xpos / fbSize.x) * 2.f - 1.0f; + pc.cuttingPlane = float(xpos / fbSize.x) * 2.f - 1.0f; iFrame = 0; } - rayGenData->iTime = (float)gprtGetTime(context) * .5f; - rayGenData->iFrame = iFrame; - - // Use this to upload all set parameters to our ray tracing device - gprtBuildShaderBindingTable(context, GPRT_SBT_RAYGEN); + pc.iTime = (float)gprtGetTime(context) * .5f; + pc.iFrame = iFrame; // Calls the GPU raygen kernel function - gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y); + gprtRayGenLaunch2D(context, rayGen, fbSize.x, fbSize.y, pc); // If a window exists, presents the framebuffer here to that window gprtBufferPresent(context, frameBuffer); diff --git a/samples/s12-swBVH/sharedCode.h b/samples/s12-swBVH/sharedCode.h index 2116b0f..aa10635 100644 --- a/samples/s12-swBVH/sharedCode.h +++ b/samples/s12-swBVH/sharedCode.h @@ -27,9 +27,17 @@ struct RayGenData { alignas(16) gprt::Buffer frameBuffer; alignas(16) gprt::Buffer accumBuffer; - LBVHData lbvh; +}; + +/* variables for the miss program */ +struct MissProgData { + alignas(16) float3 color0; + alignas(16) float3 color1; +}; +/* Constants that change each frame */ +struct PushConstants { alignas(4) float iTime; alignas(4) int iFrame; alignas(4) float cuttingPlane; @@ -40,10 +48,4 @@ struct RayGenData { alignas(16) float3 dir_du; alignas(16) float3 dir_dv; } camera; -}; - -/* variables for the miss program */ -struct MissProgData { - alignas(16) float3 color0; - alignas(16) float3 color1; -}; +}; \ No newline at end of file