diff options
| author | YONGH\yongh <yonghe@outlook.com> | 2017-10-19 18:18:21 -0400 |
|---|---|---|
| committer | YONGH\yongh <yonghe@outlook.com> | 2017-10-19 18:18:21 -0400 |
| commit | 8ff7412f988c77f21196b907820b94aa67eb6f21 (patch) | |
| tree | 27bea95dec68c42e5d3dd924da0cd8fa74f0d9e4 /tools/render-test/main.cpp | |
| parent | 88023aea669f258d66e53eab10215337a7f72853 (diff) | |
Support running and comparing execution results of compute shaders in testing framework.
Diffstat (limited to 'tools/render-test/main.cpp')
| -rw-r--r-- | tools/render-test/main.cpp | 140 |
1 files changed, 94 insertions, 46 deletions
diff --git a/tools/render-test/main.cpp b/tools/render-test/main.cpp index f2688d275..6907ba40f 100644 --- a/tools/render-test/main.cpp +++ b/tools/render-test/main.cpp @@ -49,21 +49,24 @@ static const Vertex kVertexData[kVertexCount] = { // Global variables for state to be used for rendering... -uintptr_t gConstantBufferSize; +uintptr_t gConstantBufferSize, gComputeResultBufferSize; Buffer* gConstantBuffer; InputLayout* gInputLayout; Buffer* gVertexBuffer; +Buffer* gComputeResultBuffer; ShaderProgram* gShaderProgram; // Entry point name to use for vertex/fragment shader static char const* vertexEntryPointName = "vertexMain"; static char const* fragmentEntryPointName = "fragmentMain"; +static char const* computeEntryPointName = "computeMain"; // "Profile" to use when compiling for HLSL targets // TODO: does this belong here? static char const* vertexProfileName = "vs_4_0"; static char const* fragmentProfileName = "ps_4_0"; +static char const* computeProfileName = "cs_4_0"; Error initializeShaders( ShaderCompiler* shaderCompiler) @@ -95,13 +98,21 @@ Error initializeShaders( ShaderCompileRequest compileRequest; compileRequest.source = sourceInfo; - compileRequest.vertexShader.source = sourceInfo; - compileRequest.vertexShader.name = vertexEntryPointName; - compileRequest.vertexShader.profile = vertexProfileName; - compileRequest.fragmentShader.source = sourceInfo; - compileRequest.fragmentShader.name = fragmentEntryPointName; - compileRequest.fragmentShader.profile = fragmentProfileName; - + if (gOptions.shaderType == ShaderProgramType::Graphics) + { + compileRequest.vertexShader.source = sourceInfo; + compileRequest.vertexShader.name = vertexEntryPointName; + compileRequest.vertexShader.profile = vertexProfileName; + compileRequest.fragmentShader.source = sourceInfo; + compileRequest.fragmentShader.name = fragmentEntryPointName; + compileRequest.fragmentShader.profile = fragmentProfileName; + } + else + { + compileRequest.computeShader.source = sourceInfo; + compileRequest.computeShader.name = computeEntryPointName; + compileRequest.computeShader.profile = computeProfileName; + } gShaderProgram = shaderCompiler->compileProgram(compileRequest); if( !gShaderProgram ) { @@ -111,6 +122,15 @@ Error initializeShaders( return Error::None; } +void outputComputeResult(Renderer* renderer, const char * fileName) +{ + float* data = (float*)renderer->map(gComputeResultBuffer, MapFlavor::HostRead); + FILE* f = fopen(fileName, "wt"); + for (auto i = 0u; i < gComputeResultBufferSize / sizeof(UInt); i++) + fprintf(f, "%.9g\n", data[i]); + fclose(f); +} + // // At initialization time, we are going to load and compile our Slang shader // code, and then create the D3D11 API objects we need for rendering. @@ -138,6 +158,19 @@ Error initializeInner( if(!gConstantBuffer) return Error::Unexpected; + gComputeResultBufferSize = 512 * sizeof(float); + BufferDesc computeResultBufferDesc; + computeResultBufferDesc.size = gComputeResultBufferSize; + computeResultBufferDesc.flavor = BufferFlavor::Storage; + gComputeResultBuffer = renderer->createBuffer(computeResultBufferDesc); + if (!gComputeResultBufferSize) + return Error::Unexpected; + // initialize buffer to 0 + char * ptr = (char*)renderer->map(gComputeResultBuffer, MapFlavor::HostWrite); + for (auto i = 0u; i < gComputeResultBufferSize; i++) + ptr[i] = 0; + renderer->unmap(gComputeResultBuffer); + // Input Assembler (IA) InputElementDesc inputElements[] = { @@ -195,6 +228,13 @@ void renderFrameInner( renderer->draw(3); } +void runCompute(Renderer * renderer) +{ + renderer->setShaderProgram(gShaderProgram); + renderer->setStorageBuffer(0, gComputeResultBuffer); + renderer->dispatchCompute(1, 1, 1); +} + void finalize() { } @@ -352,44 +392,52 @@ int main( // Once initialization is all complete, we show the window... ShowWindow(windowHandle, showCommand); - - // ... and enter the event loop: - for(;;) - { - MSG message; - - int result = PeekMessageW(&message, NULL, 0, 0, PM_REMOVE); - if (result != 0) - { - if (message.message == WM_QUIT) - { - return (int)message.wParam; - } - - TranslateMessage(&message); - DispatchMessageW(&message); - } - else - { - // Whenver we don't have Windows events to process, - // we render a frame. - - static const float kClearColor[] = { 0.25, 0.25, 0.25, 1.0 }; - renderer->setClearColor(kClearColor); - renderer->clearFrame(); - - renderFrameInner(renderer); - - // If we are in a mode where output is requested, we need to snapshot the back buffer here - if( gOptions.outputPath ) - { - renderer->captureScreenShot(gOptions.outputPath); - return 0; - } - - renderer->presentFrame(); - } - } + + // ... and enter the event loop: + for (;;) + { + MSG message; + + int result = PeekMessageW(&message, NULL, 0, 0, PM_REMOVE); + if (result != 0) + { + if (message.message == WM_QUIT) + { + return (int)message.wParam; + } + + TranslateMessage(&message); + DispatchMessageW(&message); + } + else + { + // Whenver we don't have Windows events to process, + // we render a frame. + static const float kClearColor[] = { 0.25, 0.25, 0.25, 1.0 }; + renderer->setClearColor(kClearColor); + renderer->clearFrame(); + + if (gOptions.shaderType == ShaderProgramType::Compute) + { + runCompute(renderer); + } + else + { + renderFrameInner(renderer); + } + // If we are in a mode where output is requested, we need to snapshot the back buffer here + if (gOptions.outputPath) + { + if (gOptions.shaderType == ShaderProgramType::Compute) + outputComputeResult(renderer, gOptions.outputPath); + else + renderer->captureScreenShot(gOptions.outputPath); + return 0; + } + + renderer->presentFrame(); + } + } return 0; } |
