From df3af75801ce2dd6a88532c05a305a9225cb2725 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Fri, 28 Feb 2025 12:46:01 +0900 Subject: [PATCH] pretty much works now --- src/CMakeLists.txt | 1 + src/cpu/CMakeLists.txt | 4 +- src/cpu/CPURenderer.cpp | 21 +++- src/main.cpp | 53 +++++----- src/metal/Compute.metal | 31 +++--- src/metal/MetalRenderer.mm | 194 +++++++++++++++++++++---------------- src/metal/MetalScene.h | 33 ++++--- 7 files changed, 192 insertions(+), 145 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7522e5c..8f219e5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,5 +10,6 @@ target_sources(RayTracer if(APPLE) add_subdirectory(metal/) endif() +add_subdirectory(cpu/) add_subdirectory(scene/) add_subdirectory(util/) diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index 7ebd341..e2819f6 100644 --- a/src/cpu/CMakeLists.txt +++ b/src/cpu/CMakeLists.txt @@ -2,5 +2,5 @@ target_sources(RayTracer PUBLIC CPURenderer.h CPURenderer.cpp - CPURenderer.h - CPURenderer.cpp) \ No newline at end of file + CPUScene.h + CPUScene.cpp) \ No newline at end of file diff --git a/src/cpu/CPURenderer.cpp b/src/cpu/CPURenderer.cpp index 537131a..516a5f1 100644 --- a/src/cpu/CPURenderer.cpp +++ b/src/cpu/CPURenderer.cpp @@ -1,21 +1,31 @@ #include "CPURenderer.h" #include "scene/Renderer.h" +#include "CPUScene.h" #include #include #include #define GLSL(...) "#version 400\n" #__VA_ARGS__ +static void glfw_error_callback(int error, const char* description) +{ + fprintf(stderr, "Glfw Error %d: %s\n", error, description); +} CPURenderer::CPURenderer() { + width = 1920; + height = 1080; glewExperimental = true; + glfwSetErrorCallback(glfw_error_callback); glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // We don't want the old OpenGL - window = glfwCreateWindow(width, height, "RayTracer", nullptr, nullptr); - glfwSwapInterval(1); + float xscale = 1, yscale = 1; + glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xscale, &yscale); + window = glfwCreateWindow(width / xscale, height / yscale, "RayTracer", nullptr, nullptr); glfwMakeContextCurrent(window); + glfwSwapInterval(1); IMGUI_CHECKVERSION(); ImGui::CreateContext(); @@ -28,6 +38,8 @@ CPURenderer::CPURenderer() ImGui_ImplOpenGL3_Init(); glewInit(); + + scene = new CPUScene(); glGenVertexArrays(1, &vao); glBindVertexArray(vao); @@ -91,6 +103,11 @@ CPURenderer::CPURenderer() glClearColor(0, 0, 0, 0); } +CPURenderer::~CPURenderer() +{ + +} + glm::vec3 rand01(glm::uvec3 x) { // pseudo-random number generator for (int i = 3; i-- > 0;) diff --git a/src/main.cpp b/src/main.cpp index 8d6d96d..61f44b7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,12 +1,11 @@ #include "scene/Renderer.h" +#include "cpu/CPURenderer.h" #include "util/ModelLoader.h" -#include "metal/MetalRenderer.h" #include int main() { - std::unique_ptr renderer = std::make_unique(); - + std::unique_ptr renderer = std::make_unique(); renderer->addDirectionalLight(DirectionalLight{ .direction = glm::normalize(glm::vec3(-0.4f, -0.3f, -0.2f)), .color = glm::vec3(1, 1, 1), @@ -15,13 +14,12 @@ int main() renderer->addModels(ModelLoader::loadModel("../../res/models/cube.fbx"), glm::mat4(glm::vec4(1.0f, 0.0f, 0.0f, 0.0f), glm::vec4(0.0f, 1.0f, 0.0f, 0.0f), glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f))); - renderer->addModels(ModelLoader::loadModel("../../res/models/cube.fbx"), - glm::mat4(glm::vec4(1.0f, 0.0f, 0.0f, 0.0f), glm::vec4(0.0f, 1.0f, 0.0f, 0.0f), glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), - glm::vec4(0.0f, 0.0f, 0.0f, 1.0f))); - renderer->generate(); + renderer->generate(); Camera camera = Camera{ .position = glm::vec3(5, 1, 2), .target = glm::vec3(0, 0, 0), + .f = 0, + .A = 0, .S_O = 6, }; RenderParameter render = RenderParameter{ @@ -33,27 +31,26 @@ int main() while (true) { - renderer->beginFrame(); - ImGui::Text("Camera Parameters"); - ImGui::InputFloat3("Position", &camera.position.x); - ImGui::InputFloat3("Target", &camera.target.x); - ImGui::InputFloat("Focal Length", &camera.f); - ImGui::InputFloat("Aperture", &camera.A); - ImGui::InputFloat("S_O", &camera.S_O); - ImGui::Text("Render Parameters"); - ImGui::InputInt2("Dimensions", (int*)&render.width); - ImGui::InputInt("Samples", (int*)&render.numSamples); - if (ImGui::Button("Render")) - { - std::cout << "Test" << std::endl; - renderer->startRender(camera, render); + renderer->beginFrame(); + ImGui::Text("Camera Parameters"); + ImGui::InputFloat3("Position", &camera.position.x); + ImGui::InputFloat3("Target", &camera.target.x); + ImGui::InputFloat("Focal Length", &camera.f); + ImGui::InputFloat("Aperture", &camera.A); + ImGui::InputFloat("S_O", &camera.S_O); + ImGui::Text("Render Parameters"); + ImGui::InputInt2("Dimensions", (int*)&render.width); + ImGui::InputInt("Samples", (int*)&render.numSamples); + if (ImGui::Button("Render")) + { + renderer->startRender(camera, render); + } + ImGui::Text("Render Stats"); + ImGui::Text("Last Sample Time: %.3f ms", renderer->getLastSampleTime()); + ImGui::Text("Average Sample Time: %.3f ms", renderer->getAverageSampleTime()); + ImGui::PlotLines("Sample Times", renderer->getSampleTimes().data(), renderer->getSampleTimes().size(), 0, 0, FLT_MAX, FLT_MAX, + ImVec2(0, 40)); + renderer->update(); } - ImGui::Text("Render Stats"); - ImGui::Text("Last Sample Time: %.3f ms", renderer->getLastSampleTime()); - ImGui::Text("Average Sample Time: %.3f ms", renderer->getAverageSampleTime()); - ImGui::PlotLines("Sample Times", renderer->getSampleTimes().data(), renderer->getSampleTimes().size(), 0, 0, FLT_MAX, FLT_MAX, - ImVec2(0, 40)); - renderer->update(); - } return 0; } diff --git a/src/metal/Compute.metal b/src/metal/Compute.metal index 824c726..d81e8a5 100644 --- a/src/metal/Compute.metal +++ b/src/metal/Compute.metal @@ -68,7 +68,7 @@ struct BRDF float3 albedo = float3(1, 1, 1); float alpha = 1; float3 specularColor = float3(1, 1, 1); - float shininess = 0.04; + float shininess = 0.004; float3 emissive = float3(0, 0, 0); MaterialType materialType; float3 evaluate(HitInfo hit, float3 viewDir, float3 lightDir, float3 lightColor) @@ -76,7 +76,7 @@ struct BRDF float3 normal = hit.normal; float diffuse = max(dot(normal, lightDir), 0.0f); float3 h = normalize(lightDir + viewDir); - float specular = pow(min(max(dot(normal, h), 0.0f), 1.0f), shininess); + float specular = pow(clamp(dot(normal, h), 0.0f, 1.0f), shininess); return (albedo * diffuse * lightColor) + float3(0.03, 0.03, 0.03); } @@ -117,7 +117,7 @@ inline T interpolateVertexAttribute(constant T *attributes, // Compute the sum of the vertex attributes weighted by the barycentric coordinates. // The barycentric coordinates sum to one. - return (1.0f - uv.x - uv.y) * T0 + uv.x * T1 + uv.y * T2; + return (1.0f - uv.x - uv.y) * T2 + uv.x * T0 + uv.y * T1; } kernel void computeKernel( @@ -129,10 +129,11 @@ kernel void computeKernel( constant packed_float2* texCoords [[buffer(2)]], constant packed_float3* normals [[buffer(3)]], constant ModelReference* modelRefs [[buffer(4)]], - constant DirectionalLight* directionalLights [[buffer(5)]], - constant PointLight* pointLights [[buffer(6)]], - constant MTLAccelerationStructureInstanceDescriptor* instances [[buffer(7)]], - instance_acceleration_structure accelerationStructure [[buffer(8)]], + constant BRDF* materials [[buffer(5)]], + constant DirectionalLight* directionalLights [[buffer(6)]], + constant PointLight* pointLights [[buffer(7)]], + constant MTLAccelerationStructureInstanceDescriptor* instances [[buffer(8)]], + instance_acceleration_structure accelerationStructure [[buffer(9)]], texture2d accumulator [[texture(0)]], texture2d image [[texture(1)]] ) @@ -201,11 +202,11 @@ kernel void computeKernel( const auto indices = indexBuffer[ref.indicesOffset + intersection.primitive_id]; info.position = interpolateVertexAttribute(positions, ref.positionOffset, indices.x, indices.y, indices.z, intersection.triangle_barycentric_coord); info.texCoords = interpolateVertexAttribute(texCoords, ref.positionOffset, indices.x, indices.y, indices.z, intersection.triangle_barycentric_coord); - info.normal = interpolateVertexAttribute(normals, ref.positionOffset, indices.x, indices.y, indices.z, intersection.triangle_barycentric_coord); + info.normal = normalize(interpolateVertexAttribute(normals, ref.positionOffset, indices.x, indices.y, indices.z, intersection.triangle_barycentric_coord)); info.normalLight = dot(info.normal, cam.direction) < 0 ? info.normal : -info.normal; BRDF brdf; - brdf.albedo = float3(0, 1, 0); + brdf.albedo = float3(0, 1, 0); float p = max(max(brdf.albedo.x, brdf.albedo.y), brdf.albedo.z); if (payload.depth > 5) @@ -229,9 +230,9 @@ kernel void computeKernel( shadowRay.max_distance = INFINITY; i.accept_any_intersection(true); intersection = i.intersect(shadowRay, accelerationStructure, 0xff); - if(intersection.type != intersection_type::none) + if(intersection.type == intersection_type::none) { - payload.accumulatedRadiance += brdf.evaluate(info, -cam.direction, shadowRay.direction, directionalLights[l].color); + payload.accumulatedRadiance += brdf.evaluate(info, -cam.direction, normalize(shadowRay.direction), directionalLights[l].color); } } for (uint l = 0; l < sample.numPointLights; ++l) @@ -243,7 +244,7 @@ kernel void computeKernel( shadowRay.max_distance = 1; i.accept_any_intersection(true); intersection = i.intersect(shadowRay, accelerationStructure, 0xff); - if (intersection.type != intersection_type::none) + if (intersection.type == intersection_type::none) { float d = length(lightDir); float illuminance = max(1 - d / pointLights[l].attenuation, 0.0f); @@ -267,7 +268,11 @@ kernel void computeKernel( payload.depth++; } float resolver = float(sample.samplesPerPixel) / float(sample.pass+1); - float4 previous = accumulator.read(threadId); + float4 previous = float4(0); + if(sample.pass != 0) + { + previous = accumulator.read(threadId); + } float4 result = previous + float4(payload.accumulatedRadiance / float(sample.samplesPerPixel), 0); accumulator.write(result, threadId); image.write(pow(max(result * resolver, 0), float4(0.45f)), threadId); diff --git a/src/metal/MetalRenderer.mm b/src/metal/MetalRenderer.mm index 5208e2d..010f9b0 100644 --- a/src/metal/MetalRenderer.mm +++ b/src/metal/MetalRenderer.mm @@ -14,11 +14,10 @@ id drawable; id device; id library; id queue; -id renderQueue; id function; id computePipeline; -id accumulator; -id resultTexture; +id accumulator = nullptr; +id resultTexture = nullptr; MTLRenderPassDescriptor* renderPass; id renderEncoder; @@ -34,54 +33,56 @@ MetalRenderer::MetalRenderer() width = 1920; height = 1080; device = MTLCreateSystemDefaultDevice(); - + library = [device newDefaultLibrary]; - + queue = [device newCommandQueue]; - renderQueue = [device newCommandQueue]; - + scene = new MetalScene(device, queue); - - function = [library newFunctionWithName:@"computeKernel"]; - + + function = [library newFunctionWithName:@"computeKernel"]; + NSError* error; - computePipeline = [device newComputePipelineStateWithFunction:function error:&error]; + computePipeline = [device newComputePipelineStateWithFunction:function error:&error]; IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - ImGuiIO& io = ImGui::GetIO(); - io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls glfwSetErrorCallback(glfw_error_callback); glfwInit(); float xscale = 1, yscale = 1; glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xscale, &yscale); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); handle = glfwCreateWindow(width / xscale, height / yscale, "RayTracer", nullptr, nullptr); - - - ImGui_ImplGlfw_InitForOpenGL(handle, false); + + ImGui_ImplGlfw_InitForOpenGL(handle, true); ImGui_ImplMetal_Init(device); NSWindow* cocoaWindow = glfwGetCocoaWindow(handle); metalLayer = [CAMetalLayer layer]; metalLayer.device = device; metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; - [[cocoaWindow contentView] setLayer:metalLayer]; - [[cocoaWindow contentView] setWantsLayer:true]; - renderPass = [[MTLRenderPassDescriptor alloc] init]; - - MTLRenderPipelineDescriptor *renderDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; - - renderDescriptor.vertexFunction = [library newFunctionWithName:@"copyVertex"]; - renderDescriptor.fragmentFunction = [library newFunctionWithName:@"copyFragment"]; - - renderDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm; - - pipelineState = [device newRenderPipelineStateWithDescriptor:renderDescriptor error:&error]; + [[cocoaWindow contentView] setLayer:metalLayer]; + [[cocoaWindow contentView] setWantsLayer:true]; + renderPass = [[MTLRenderPassDescriptor alloc] init]; + + MTLRenderPipelineDescriptor *renderDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; + + renderDescriptor.vertexFunction = [library newFunctionWithName:@"copyVertex"]; + renderDescriptor.fragmentFunction = [library newFunctionWithName:@"copyFragment"]; + + renderDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm; + + pipelineState = [device newRenderPipelineStateWithDescriptor:renderDescriptor error:&error]; + + [renderDescriptor release]; } -MetalRenderer::~MetalRenderer() {} +MetalRenderer::~MetalRenderer() { + [renderPass release]; +} void MetalRenderer::addPointLight(PointLight point) { scene->addPointLight(point); } void MetalRenderer::addDirectionalLight(DirectionalLight dir) { scene->addDirectionalLight(dir); } @@ -91,14 +92,16 @@ void MetalRenderer::generate() { scene->generate(); } void MetalRenderer::beginFrame() { - glfwPollEvents(); + @autoreleasepool { + + glfwPollEvents(); int w, h; glfwGetFramebufferSize(handle, &w, &h); framebufferWidth = width; framebufferHeight = height; metalLayer.drawableSize = CGSizeMake(framebufferWidth, framebufferHeight); -drawable = [metalLayer nextDrawable]; - renderCmd = [renderQueue commandBuffer]; + drawable = [metalLayer nextDrawable]; + renderCmd = [queue commandBuffer]; renderPass.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 0); renderPass.colorAttachments[0].texture = drawable.texture; renderPass.colorAttachments[0].loadAction = MTLLoadActionClear; @@ -113,18 +116,25 @@ drawable = [metalLayer nextDrawable]; // Draw a quad which fills the screen. [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:6]; + + [renderEncoder retain]; + [renderCmd retain]; + [drawable retain]; + } } void MetalRenderer::update() { + @autoreleasepool { ImGui::Render(); ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), renderCmd, renderEncoder); [renderEncoder endEncoding]; + [renderEncoder release]; [renderCmd presentDrawable:drawable]; [renderCmd commit]; - [renderCmd release]; - [renderEncoder release]; - [drawable release]; + [renderCmd release]; + [drawable release]; + } } void MetalRenderer::render(Camera camera, RenderParameter parameter) @@ -140,6 +150,11 @@ void MetalRenderer::render(Camera camera, RenderParameter parameter) .height = parameter.height, }; + if(accumulator != nullptr) + { + [accumulator release]; + [resultTexture release]; + } MTLTextureDescriptor* texDescriptor = [[MTLTextureDescriptor alloc] init]; [texDescriptor setWidth:parameter.width]; [texDescriptor setHeight:parameter.height]; @@ -147,58 +162,69 @@ void MetalRenderer::render(Camera camera, RenderParameter parameter) [texDescriptor setUsage:MTLTextureUsageShaderWrite | MTLTextureUsageShaderRead]; accumulator = [device newTextureWithDescriptor:texDescriptor]; resultTexture = [device newTextureWithDescriptor:texDescriptor]; + [texDescriptor release]; for (uint i = 0; i < parameter.numSamples; ++i) { - id cmdBuffer = [queue commandBuffer]; - id encoder = [cmdBuffer computeCommandEncoder]; - // cmdBuffer->addCompletedHandler([this](MTL::CommandBuffer* cmdBuffer) - // { std::memcpy(image.data(), resultTexture->buffer(), image.size() * sizeof(glm::vec3)); }); - + if(!running) + return; + @autoreleasepool{ + id cmdBuffer = [queue commandBuffer]; + id encoder = [cmdBuffer computeCommandEncoder]; + // cmdBuffer->addCompletedHandler([this](MTL::CommandBuffer* cmdBuffer) + // { std::memcpy(image.data(), resultTexture->buffer(), image.size() * sizeof(glm::vec3)); }); + SampleParams sample = { - .pass = i, - .samplesPerPixel = parameter.numSamples, - .numDirectionalLights = scene->getNumDirLights(), - .numPointLights = scene->getNumPointLights(), + .pass = i, + .samplesPerPixel = parameter.numSamples, + .numDirectionalLights = scene->getNumDirLights(), + .numPointLights = scene->getNumPointLights(), }; - [encoder setComputePipelineState:computePipeline]; - [encoder setBuffer:scene->indicesBuffer offset:0 atIndex:0]; - [encoder setBuffer:scene->positionBuffer offset:0 atIndex:1]; - [encoder setBuffer:scene->texCoordsBuffer offset:0 atIndex:2]; - [encoder setBuffer:scene->normalBuffer offset:0 atIndex:3]; - [encoder setBuffer:scene->modelRefsBuffer offset:0 atIndex:4]; - [encoder setBuffer:scene->directionalLightBuffer offset:0 atIndex:5]; - [encoder setBuffer:scene->pointLightBuffer offset:0 atIndex:6]; - [encoder setBuffer:scene->instanceBuffer offset:0 atIndex:7]; - [encoder setAccelerationStructure:scene->accelerationStructure atBufferIndex:8]; - [encoder setTexture:accumulator atIndex:0]; - [encoder setTexture:resultTexture atIndex:1]; - [encoder setBytes:&gpuCam length:sizeof(GPUCamera) atIndex:9]; - [encoder setBytes:&sample length:sizeof(SampleParams) atIndex:10]; - [encoder useResource:scene->instanceBuffer usage:MTLResourceUsageRead]; - [encoder useResource:scene->positionBuffer usage:MTLResourceUsageRead]; - [encoder useResource:scene->texCoordsBuffer usage:MTLResourceUsageRead]; - [encoder useResource:scene->normalBuffer usage:MTLResourceUsageRead]; - [encoder useResource:scene->modelRefsBuffer usage:MTLResourceUsageRead]; - if (scene->getNumDirLights() > 0) - { - [encoder useResource:scene->directionalLightBuffer usage:MTLResourceUsageRead]; - } - if (scene->getNumPointLights() > 0) - { + [encoder setComputePipelineState:computePipeline]; + [encoder setBuffer:scene->indicesBuffer offset:0 atIndex:0]; + [encoder setBuffer:scene->positionBuffer offset:0 atIndex:1]; + [encoder setBuffer:scene->texCoordsBuffer offset:0 atIndex:2]; + [encoder setBuffer:scene->normalBuffer offset:0 atIndex:3]; + [encoder setBuffer:scene->modelRefsBuffer offset:0 atIndex:4]; + [encoder setBuffer:scene->directionalLightBuffer offset:0 atIndex:6]; + [encoder setBuffer:scene->pointLightBuffer offset:0 atIndex:7]; + [encoder setBuffer:scene->instanceBuffer offset:0 atIndex:8]; + [encoder setAccelerationStructure:scene->accelerationStructure atBufferIndex:9]; + [encoder setTexture:accumulator atIndex:0]; + [encoder setTexture:resultTexture atIndex:1]; + [encoder setBytes:&gpuCam length:sizeof(GPUCamera) atIndex:10]; + [encoder setBytes:&sample length:sizeof(SampleParams) atIndex:11]; + [encoder useResource:scene->instanceBuffer usage:MTLResourceUsageRead]; + [encoder useResource:scene->positionBuffer usage:MTLResourceUsageRead]; + [encoder useResource:scene->texCoordsBuffer usage:MTLResourceUsageRead]; + [encoder useResource:scene->normalBuffer usage:MTLResourceUsageRead]; + [encoder useResource:scene->modelRefsBuffer usage:MTLResourceUsageRead]; + if (scene->getNumDirLights() > 0) + { + [encoder useResource:scene->directionalLightBuffer usage:MTLResourceUsageRead]; + } + if (scene->getNumPointLights() > 0) + { [encoder useResource:scene->pointLightBuffer usage:MTLResourceUsageRead]; + } + [encoder useResource:scene->instanceBuffer usage:MTLResourceUsageRead]; + [encoder useResource:scene->accelerationStructure usage:MTLResourceUsageRead]; + [encoder useResource:accumulator usage:MTLResourceUsageWrite]; + [encoder useResource:resultTexture usage:MTLResourceUsageWrite]; + NSUInteger width = (NSUInteger)parameter.width; + NSUInteger height = (NSUInteger)parameter.height; + MTLSize threadsPerThreadgroup = MTLSizeMake(8, 8, 1); + MTLSize threadgroups = MTLSizeMake((width + threadsPerThreadgroup.width - 1) / threadsPerThreadgroup.width, + (height + threadsPerThreadgroup.height - 1) / threadsPerThreadgroup.height, 1); + [encoder dispatchThreadgroups:threadgroups threadsPerThreadgroup:threadsPerThreadgroup]; + [encoder endEncoding]; + [cmdBuffer commit]; + [cmdBuffer addCompletedHandler:^(id _Nonnull cmd) { + sampleTimes.push_back((cmd.GPUEndTime - cmd.GPUStartTime) * 1000.f); + if(sampleTimes.size() > 200) + { + sampleTimes.erase(sampleTimes.begin()); + } + }]; } - [encoder useResource:scene->instanceBuffer usage:MTLResourceUsageRead]; - [encoder useResource:scene->accelerationStructure usage:MTLResourceUsageRead]; - [encoder useResource:accumulator usage:MTLResourceUsageWrite]; - [encoder useResource:resultTexture usage:MTLResourceUsageWrite]; - NSUInteger width = (NSUInteger)parameter.width; - NSUInteger height = (NSUInteger)parameter.height; - MTLSize threadsPerThreadgroup = MTLSizeMake(8, 8, 1); - MTLSize threadgroups = MTLSizeMake((width + threadsPerThreadgroup.width - 1) / threadsPerThreadgroup.width, - (height + threadsPerThreadgroup.height - 1) / threadsPerThreadgroup.height, 1); - [encoder dispatchThreadgroups:threadgroups threadsPerThreadgroup:threadsPerThreadgroup]; - [encoder endEncoding]; - [cmdBuffer commit]; - sampleTimes.push_back(0); } } diff --git a/src/metal/MetalScene.h b/src/metal/MetalScene.h index 069897f..ce79fee 100644 --- a/src/metal/MetalScene.h +++ b/src/metal/MetalScene.h @@ -6,24 +6,25 @@ class MetalScene : public Scene { public: - MetalScene(id device, id queue); - virtual ~MetalScene(); + MetalScene(id device, id queue); + virtual ~MetalScene(); - virtual void createRayTracingHierarchy() override; - - id newAccelerationStructureWithDescriptor(MTLAccelerationStructureDescriptor* descriptor); + virtual void createRayTracingHierarchy() override; + + id newAccelerationStructureWithDescriptor(MTLAccelerationStructureDescriptor* descriptor); - id device; - id queue; + id device; + id queue; - id indicesBuffer; - id positionBuffer; - id texCoordsBuffer; - id normalBuffer; - id modelRefsBuffer; - id directionalLightBuffer; - id pointLightBuffer; - id instanceBuffer; + id indicesBuffer; + id positionBuffer; + id texCoordsBuffer; + id normalBuffer; + id modelRefsBuffer; + id materialsBuffer; + id directionalLightBuffer; + id pointLightBuffer; + id instanceBuffer; - id accelerationStructure; + id accelerationStructure; };