diff options
| author | Gangzheng Tong <tonggangzheng@gmail.com> | 2025-07-08 23:44:56 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-09 06:44:56 +0000 |
| commit | 43d0c2100ef1a5df4b54525e50eb29fe7c39ec16 (patch) | |
| tree | 25ec4fb9c726115f90bdaa9878f2f4ca372ad0a6 /examples/model-viewer | |
| parent | 00746bf09047cdf01c19dac513a532bcf3ed3ea3 (diff) | |
Convert gfx unit tests and examples to use slang-rhi (#7577)
* Port first gfx unit test to slang-rhi
* port triangle example to use slang-rhi
* port platform-test to slang-rhi
* Update platform-test to throttle mouse move events
* port gpu-printing example to use slang-rhi
* port model-viewer example to use slang-rhi
* port ray-tracing example to use slang-rhi
* port ray-tracing pipeline example to use slang-rhi
* port reflection parameter blocks example to use slang-rhi
* port shader-object example to use slang-rhi
* port shader-toy example to use slang-rhi
* Port most of tests to slang-rhi
* port link-time-constant-array-size to use slang-rhi
* Fix tests and find matching tests in slang-rhi
* port autodiff-texture
* remove gfx target; port nv-aftermath-example
* update include path for shader-cursor.h
* Disabled 2 more ported tests
* fix build error
* remove gfx test
* put slang-rhi (static-lib) before slang (shared)
* format code (#7621)
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* add debug callback
* format code (#7649)
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Address review comments; revert back to use SLANG_CHECK_MSG
---------
Co-authored-by: slangbot <ellieh+slangbot@nvidia.com>
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Diffstat (limited to 'examples/model-viewer')
| -rw-r--r-- | examples/model-viewer/main.cpp | 117 |
1 files changed, 74 insertions, 43 deletions
diff --git a/examples/model-viewer/main.cpp b/examples/model-viewer/main.cpp index 8bbc8ec88..9c1c763f2 100644 --- a/examples/model-viewer/main.cpp +++ b/examples/model-viewer/main.cpp @@ -25,17 +25,17 @@ // and parameter binding. // #include "examples/example-base/example-base.h" -#include "gfx-util/shader-cursor.h" #include "platform/gui.h" #include "platform/model.h" #include "platform/vector-math.h" #include "platform/window.h" -#include "slang-gfx.h" +#include "slang-rhi.h" #include <map> +#include <slang-rhi/shader-cursor.h> #include <sstream> -using namespace gfx; +using namespace rhi; using Slang::RefObject; using Slang::RefPtr; @@ -121,12 +121,12 @@ struct RendererContext // At this point, `composedProgram` represents the shader program // we want to run, and the compute shader there have been checked. - // We can create a `gfx::IShaderProgram` object from `composedProgram` + // We can create a `IShaderProgram` object from `composedProgram` // so it may be used by the graphics layer. - gfx::IShaderProgram::Desc programDesc = {}; + ShaderProgramDesc programDesc = {}; programDesc.slangGlobalScope = composedProgram.get(); - shaderProgram = device->createProgram(programDesc); + shaderProgram = device->createShaderProgram(programDesc); // Get other shader types that we will use for creating shader objects. perViewShaderType = slangReflection->findTypeByName("PerView"); @@ -175,7 +175,7 @@ struct SimpleMaterial : Material auto program = context->slangReflection; auto shaderType = program->findTypeByName("SimpleMaterial"); shaderObject = context->device->createShaderObject(shaderType); - gfx::ShaderCursor cursor(shaderObject); + ShaderCursor cursor(shaderObject); cursor["diffuseColor"].setData(&diffuseColor, sizeof(diffuseColor)); cursor["specularColor"].setData(&specularColor, sizeof(specularColor)); cursor["specularity"].setData(&specularity, sizeof(specularity)); @@ -201,8 +201,8 @@ struct Model : RefObject { typedef platform::ModelLoader::Vertex Vertex; - ComPtr<IBufferResource> vertexBuffer; - ComPtr<IBufferResource> indexBuffer; + ComPtr<IBuffer> vertexBuffer; + ComPtr<IBuffer> indexBuffer; PrimitiveTopology primitiveTopology; int vertexCount; int indexCount; @@ -383,16 +383,19 @@ struct LightEnvLayout : public RefObject // struct LightArrayLayout : RefObject { - Int maximumCount = 0; + SlangInt maximumCount = 0; std::string typeName; }; std::vector<LightArrayLayout> lightArrayLayouts; - std::map<slang::TypeReflection*, Int> mapLightTypeToArrayIndex; + std::map<slang::TypeReflection*, SlangInt> mapLightTypeToArrayIndex; slang::TypeReflection* shaderType = nullptr; - void addLightType(RendererContext* context, slang::TypeReflection* lightType, Int maximumCount) + void addLightType( + RendererContext* context, + slang::TypeReflection* lightType, + SlangInt maximumCount) { - Int arrayIndex = (Int)lightArrayLayouts.size(); + SlangInt arrayIndex = (SlangInt)lightArrayLayouts.size(); LightArrayLayout layout; layout.maximumCount = maximumCount; @@ -419,12 +422,12 @@ struct LightEnvLayout : public RefObject } template<typename T> - void addLightType(RendererContext* context, Int maximumCount) + void addLightType(RendererContext* context, SlangInt maximumCount) { addLightType(context, getShaderType<T>(context), maximumCount); } - Int getArrayIndexForType(slang::TypeReflection* lightType) + SlangInt getArrayIndexForType(slang::TypeReflection* lightType) { auto iter = mapLightTypeToArrayIndex.find(lightType); if (iter != mapLightTypeToArrayIndex.end()) @@ -647,7 +650,7 @@ struct ModelViewer : WindowedAppBase RefPtr<LightEnv> lightEnv; // The pipeline state object we will use to draw models. - ComPtr<IPipelineState> gPipelineState; + ComPtr<IPipeline> gPipelineState; // During startup the application will load one or more models and // add them to the `gModels` list. @@ -762,23 +765,27 @@ struct ModelViewer : WindowedAppBase InputElementDesc inputElements[] = { - {"POSITION", 0, Format::R32G32B32_FLOAT, offsetof(Model::Vertex, position)}, - {"NORMAL", 0, Format::R32G32B32_FLOAT, offsetof(Model::Vertex, normal)}, - {"UV", 0, Format::R32G32_FLOAT, offsetof(Model::Vertex, uv)}, + {"POSITION", 0, Format::RGB32Float, offsetof(Model::Vertex, position)}, + {"NORMAL", 0, Format::RGB32Float, offsetof(Model::Vertex, normal)}, + {"UV", 0, Format::RG32Float, offsetof(Model::Vertex, uv)}, }; auto inputLayout = gDevice->createInputLayout(sizeof(Model::Vertex), &inputElements[0], 3); if (!inputLayout) return SLANG_FAIL; // Create the pipeline state object for drawing models. - GraphicsPipelineStateDesc pipelineStateDesc = {}; + RenderPipelineDesc pipelineStateDesc = {}; pipelineStateDesc.program = context.shaderProgram; - pipelineStateDesc.framebufferLayout = gFramebufferLayout; pipelineStateDesc.inputLayout = inputLayout; - pipelineStateDesc.primitiveType = PrimitiveType::Triangle; + pipelineStateDesc.primitiveTopology = PrimitiveTopology::TriangleList; pipelineStateDesc.depthStencil.depthFunc = ComparisonFunc::LessEqual; pipelineStateDesc.depthStencil.depthTestEnable = true; - gPipelineState = gDevice->createGraphicsPipelineState(pipelineStateDesc); + // Set up color target + ColorTargetDesc colorTarget = {}; + colorTarget.format = Format::RGBA8Unorm; + pipelineStateDesc.targetCount = 1; + pipelineStateDesc.targets = &colorTarget; + gPipelineState = gDevice->createRenderPipeline(pipelineStateDesc); // We will create a lighting environment layout that can hold a few point // and directional lights, and then initialize a lighting environment @@ -813,7 +820,7 @@ struct ModelViewer : WindowedAppBase // logic to see how the application will drive the `RenderContext` // type to perform both shader parameter binding and code specialization. // - void renderFrame(int frameIndex) override + void renderFrame(ITexture* texture) override { // In order to see that things are rendering properly we need some // kind of animation, so we will compute a crude delta-time value here. @@ -871,22 +878,35 @@ struct ModelViewer : WindowedAppBase view = glm::translate(view, -cameraPosition); glm::mat4x4 viewProjection = projection * view; - auto deviceInfo = gDevice->getDeviceInfo(); + auto deviceInfo = gDevice->getInfo(); + // Use identity matrix for correction + static const float kIdentity[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; glm::mat4x4 correctionMatrix; - memcpy(&correctionMatrix, deviceInfo.identityProjectionMatrix, sizeof(float) * 16); + memcpy(&correctionMatrix, kIdentity, sizeof(float) * 16); viewProjection = correctionMatrix * viewProjection; // glm uses column-major layout, we need to translate it to row-major. viewProjection = glm::transpose(viewProjection); - auto drawCommandBuffer = gTransientHeaps[frameIndex]->createCommandBuffer(); - auto drawCommandEncoder = - drawCommandBuffer->encodeRenderCommands(gRenderPass, gFramebuffers[frameIndex]); - gfx::Viewport viewport = {}; - viewport.maxZ = 1.0f; - viewport.extentX = (float)clientRect.width; - viewport.extentY = (float)clientRect.height; - drawCommandEncoder->setViewportAndScissor(viewport); - drawCommandEncoder->setPrimitiveTopology(PrimitiveTopology::TriangleList); + auto drawCommandEncoder = gQueue->createCommandEncoder(); + + ComPtr<ITextureView> textureView = gDevice->createTextureView(texture, {}); + RenderPassColorAttachment colorAttachment = {}; + colorAttachment.view = textureView; + colorAttachment.loadOp = LoadOp::Clear; + + RenderPassDesc renderPass = {}; + renderPass.colorAttachments = &colorAttachment; + renderPass.colorAttachmentCount = 1; + + auto renderEncoder = drawCommandEncoder->beginRenderPass(renderPass); + + RenderState renderState = {}; + renderState.viewports[0] = + Viewport::fromSize((float)clientRect.width, (float)clientRect.height); + renderState.viewportCount = 1; + renderState.scissorRects[0] = + ScissorRect::fromSize((float)clientRect.width, (float)clientRect.height); + renderState.scissorRectCount = 1; // We are only rendering one view, so we can fill in a per-view // shader object once and use it across all draw calls. @@ -903,8 +923,10 @@ struct ModelViewer : WindowedAppBase // for (auto& model : gModels) { - drawCommandEncoder->setVertexBuffer(0, model->vertexBuffer); - drawCommandEncoder->setIndexBuffer(model->indexBuffer, Format::R32_UINT); + renderState.vertexBuffers[0] = model->vertexBuffer; + renderState.vertexBufferCount = 1; + renderState.indexBuffer = model->indexBuffer; + renderState.indexFormat = IndexFormat::Uint32; // For each model we provide a parameter // block that holds the per-model transformation // parameters, corresponding to the `PerModel` type @@ -932,7 +954,12 @@ struct ModelViewer : WindowedAppBase for (auto& mesh : model->meshes) { // Set the pipeline and binding state for drawing each mesh. - auto rootObject = drawCommandEncoder->bindPipeline(gPipelineState); + auto rootObject = renderEncoder->bindPipeline( + static_cast<IRenderPipeline*>(gPipelineState.get())); + + // Apply render state + renderEncoder->setRenderState(renderState); + ShaderCursor rootCursor(rootObject); rootCursor["gViewParams"].setObject(viewShaderObject); rootCursor["gModelParams"].setObject(modelShaderObject); @@ -953,16 +980,20 @@ struct ModelViewer : WindowedAppBase // All the shader parameters and pipeline states have been set up, // we can now issue a draw call for the mesh. - drawCommandEncoder->drawIndexed(mesh->indexCount, mesh->firstIndex); + DrawArguments drawArgs = {}; + // `drawArgs.vertexCount` is actually `indexCount` for the `DrawIndexed` Graphics + // API + drawArgs.vertexCount = mesh->indexCount; + drawArgs.startIndexLocation = mesh->firstIndex; + renderEncoder->drawIndexed(drawArgs); } } - drawCommandEncoder->endEncoding(); - drawCommandBuffer->close(); - gQueue->executeCommandBuffer(drawCommandBuffer); + renderEncoder->end(); + gQueue->submit(drawCommandEncoder->finish()); if (!isTestMode()) { - gSwapchain->present(); + gSurface->present(); } } }; |
