diff options
| -rw-r--r-- | examples/hello/README.md | 9 | ||||
| -rw-r--r-- | examples/hello/hello.cpp | 782 | ||||
| -rw-r--r-- | examples/hello/hello.slang | 45 | ||||
| -rw-r--r-- | examples/hello/hello.vcxproj | 14 | ||||
| -rw-r--r-- | premake5.lua | 30 | ||||
| -rw-r--r-- | slang.sln | 11 | ||||
| -rw-r--r-- | tools/render-test/options.h | 4 | ||||
| -rw-r--r-- | tools/render-test/png-serialize-util.h | 6 | ||||
| -rw-r--r-- | tools/render-test/render-test.vcxproj | 42 | ||||
| -rw-r--r-- | tools/render-test/render-test.vcxproj.filters | 93 | ||||
| -rw-r--r-- | tools/render-test/shader-input-layout.h | 2 | ||||
| -rw-r--r-- | tools/render-test/window.h | 10 | ||||
| -rw-r--r-- | tools/slang-graphics/circular-resource-heap-d3d12.cpp (renamed from tools/render-test/circular-resource-heap-d3d12.cpp) | 24 | ||||
| -rw-r--r-- | tools/slang-graphics/circular-resource-heap-d3d12.h (renamed from tools/render-test/circular-resource-heap-d3d12.h) | 68 | ||||
| -rw-r--r-- | tools/slang-graphics/d3d-util.cpp (renamed from tools/render-test/d3d-util.cpp) | 2 | ||||
| -rw-r--r-- | tools/slang-graphics/d3d-util.h (renamed from tools/render-test/d3d-util.h) | 2 | ||||
| -rw-r--r-- | tools/slang-graphics/descriptor-heap-d3d12.cpp (renamed from tools/render-test/descriptor-heap-d3d12.cpp) | 6 | ||||
| -rw-r--r-- | tools/slang-graphics/descriptor-heap-d3d12.h (renamed from tools/render-test/descriptor-heap-d3d12.h) | 20 | ||||
| -rw-r--r-- | tools/slang-graphics/render-d3d11.cpp (renamed from tools/render-test/render-d3d11.cpp) | 6 | ||||
| -rw-r--r-- | tools/slang-graphics/render-d3d11.h (renamed from tools/render-test/render-d3d11.h) | 4 | ||||
| -rw-r--r-- | tools/slang-graphics/render-d3d12.cpp (renamed from tools/render-test/render-d3d12.cpp) | 6 | ||||
| -rw-r--r-- | tools/slang-graphics/render-d3d12.h (renamed from tools/render-test/render-d3d12.h) | 4 | ||||
| -rw-r--r-- | tools/slang-graphics/render-gl.cpp (renamed from tools/render-test/render-gl.cpp) | 38 | ||||
| -rw-r--r-- | tools/slang-graphics/render-gl.h (renamed from tools/render-test/render-gl.h) | 4 | ||||
| -rw-r--r-- | tools/slang-graphics/render-vk.cpp (renamed from tools/render-test/render-vk.cpp) | 156 | ||||
| -rw-r--r-- | tools/slang-graphics/render-vk.h (renamed from tools/render-test/render-vk.h) | 4 | ||||
| -rw-r--r-- | tools/slang-graphics/render.cpp (renamed from tools/render-test/render.cpp) | 2 | ||||
| -rw-r--r-- | tools/slang-graphics/render.h (renamed from tools/render-test/render.h) | 2 | ||||
| -rw-r--r-- | tools/slang-graphics/resource-d3d12.cpp (renamed from tools/render-test/resource-d3d12.cpp) | 4 | ||||
| -rw-r--r-- | tools/slang-graphics/resource-d3d12.h (renamed from tools/render-test/resource-d3d12.h) | 8 | ||||
| -rw-r--r-- | tools/slang-graphics/slang-graphics.vcxproj | 212 | ||||
| -rw-r--r-- | tools/slang-graphics/slang-graphics.vcxproj.filters | 111 | ||||
| -rw-r--r-- | tools/slang-graphics/surface.cpp (renamed from tools/render-test/surface.cpp) | 16 | ||||
| -rw-r--r-- | tools/slang-graphics/surface.h (renamed from tools/render-test/surface.h) | 18 | ||||
| -rw-r--r-- | tools/slang-graphics/vk-api.cpp (renamed from tools/render-test/vk-api.cpp) | 16 | ||||
| -rw-r--r-- | tools/slang-graphics/vk-api.h (renamed from tools/render-test/vk-api.h) | 10 | ||||
| -rw-r--r-- | tools/slang-graphics/vk-device-queue.cpp (renamed from tools/render-test/vk-device-queue.cpp) | 20 | ||||
| -rw-r--r-- | tools/slang-graphics/vk-device-queue.h (renamed from tools/render-test/vk-device-queue.h) | 12 | ||||
| -rw-r--r-- | tools/slang-graphics/vk-module.cpp (renamed from tools/render-test/vk-module.cpp) | 14 | ||||
| -rw-r--r-- | tools/slang-graphics/vk-module.h (renamed from tools/render-test/vk-module.h) | 4 | ||||
| -rw-r--r-- | tools/slang-graphics/vk-swap-chain.cpp (renamed from tools/render-test/vk-swap-chain.cpp) | 46 | ||||
| -rw-r--r-- | tools/slang-graphics/vk-swap-chain.h (renamed from tools/render-test/vk-swap-chain.h) | 12 | ||||
| -rw-r--r-- | tools/slang-graphics/vk-util.cpp (renamed from tools/render-test/vk-util.cpp) | 2 | ||||
| -rw-r--r-- | tools/slang-graphics/vk-util.h (renamed from tools/render-test/vk-util.h) | 14 | ||||
| -rw-r--r-- | tools/slang-graphics/window.cpp | 245 | ||||
| -rw-r--r-- | tools/slang-graphics/window.h | 69 |
46 files changed, 1298 insertions, 931 deletions
diff --git a/examples/hello/README.md b/examples/hello/README.md index a571bb274..31a983428 100644 --- a/examples/hello/README.md +++ b/examples/hello/README.md @@ -1,9 +1,12 @@ Slang "Hello World" Example =========================== -The goal of this example is to demonstrate an almost minimal application that uses Slang for shading, and D3D11 for rendering. +The goal of this example is to demonstrate an almost minimal application that uses Slang for shading. + +The `hello.slang` file contains simple vertex and fragment shader entry points. The shader code should compile as either Slang or HLSL code (that is, this example does not show off any new Slang language features). -The `hello.slang` file contains simple vertex and fragment shader entry points. The `hello.cpp` file contains the C++ application code, showing how to use the Slang C API to load and compile the shader code to DirectX shader bytecode (DXBC). +The application perform rendering using the D3D11 API, through a platform and graphics API abstraction layer that is implemented in `tools/slang-graphics`. +Note that this abstraction layer is *not* required in order to work with Slang, and it is just there to help us write example applications more conveniently. -Note that this example is not intended to demonstrate good practices for integrating Slang into a production engine; the goal is merely to use the minimum amount of code possible to demonstrate a complete applicaiton that uses Slang. +This example is not necessarily representative of best practices for integrating Slang into a production engine; the goal is merely to use the minimum amount of code possible to demonstrate a complete applicaiton that uses Slang. diff --git a/examples/hello/hello.cpp b/examples/hello/hello.cpp index aef6b90d1..a5d90a3f4 100644 --- a/examples/hello/hello.cpp +++ b/examples/hello/hello.cpp @@ -1,43 +1,192 @@ // hello.cpp -// In order to use the Slang API, we need to include its header - +// This file implements an extremely simple example of loading and +// executing a Slang shader program. +// +// The comments in the file will attempt to explain concepts as +// they are introduced. +// +// Of course, in order to use the Slang API, we need to include +// its header. We have set up the build options for this project +// so that it is as simple as: +// #include <slang.h> +// +// Other build setups are possible, and Slang doesn't assume that +// its include directory must be added to your global include +// path. + +// For the purposes of keeping the demo code as simple as possible, +// while still retaining some level of portability, our examples +// make use of a small platform and graphics API abstraction layer, +// which is included in the Slang source distribution under the +// `tools/` directory. +// +// Applications can of course use Slang without ever touching this +// abstraction layer, so we will not focus on it when explaining +// examples, except in places where best practices for interacting +// with Slang may depend on an application/engine making certain +// design choices in their abstraction layer. +// +#include "slang-graphics/render.h" +#include "slang-graphics/render-d3d11.h" +#include "slang-graphics/window.h" +using namespace slang_graphics; + +// We will start with a function that will invoke the Slang compiler +// to generate target-specific code from a shader file, and then +// use that to initialize an API shader program. +// +// Note that `Renderer` and `ShaderProgram` here are types from +// the graphics API abstraction layer, and *not* part of the +// Slang API. This function is representative of code that a user +// might write to integrate Slang into their renderer/engine. +// +ShaderProgram* loadShaderProgram(Renderer* renderer) +{ + // First, we need to create a "session" for interacting with the Slang + // compiler. This scopes all of our application's interactions + // with the Slang library. At the moment, creating a session causes + // Slang to load and validate its standard library, so this is a + // somewhat heavy-weight operation. When possible, an application + // should try to re-use the same session across multiple compiles. + SlangSession* slangSession = spCreateSession(NULL); -// We will be rendering with Direct3D 11, so we need to include -// the Windows and D3D11 headers + // A compile request represents a single invocation of the compiler, + // to process some inputs and produce outputs (or errors). + SlangCompileRequest* slangRequest = spCreateCompileRequest(slangSession); -#define WIN32_LEAN_AND_MEAN -#define NOMINMAX -#include <Windows.h> -#undef WIN32_LEAN_AND_MEAN -#undef NOMINMAX + // We would like to request a single target (output) format: DirectX shader bytecode (DXBC) + int targetIndex = spAddCodeGenTarget(slangRequest, SLANG_DXBC); -#include <d3d11_2.h> -#include <d3dcompiler.h> + // We will specify the desired "profile" for this one target in terms of the + // DirectX "shader model" that should be supported. + spSetTargetProfile(slangRequest, targetIndex, spFindProfile(slangSession, "sm_4_0")); -// We will use the C standard library just for printing error messages. -#include <stdio.h> + // A compile request can include one or more "translation units," which more or + // less amount to individual source files (think `.c` files, not the `.h` files they + // might include). + // + // For this example, our code will all be in the Slang language. The user may + // also specify HLSL input here, but that currently doesn't affect the compiler's + // behavior much. + int translationUnitIndex = spAddTranslationUnit(slangRequest, SLANG_SOURCE_LANGUAGE_SLANG, nullptr); -#ifdef _MSC_VER -#include <stddef.h> -#if (_MSC_VER < 1900) -#define snprintf sprintf_s -#endif -#endif -// + // We will load source code for our translation unit from the file `hello.slang`. + // There are also variations of this API for adding source code from application-provided buffers. + spAddTranslationUnitSourceFile(slangRequest, translationUnitIndex, "hello.slang"); -static int gWindowWidth = 1024; -static int gWindowHeight = 768; + // Next we will specify the entry points we'd like to compile. + // It is often convenient to put more than one entry point in the same file, + // and the Slang API makes it convenient to use a single run of the compiler + // to compile all entry points. + // + // For each entry point, we need to specify the name of a function, the + // translation unit in which that function can be found, and the stage + // that we need to compile for (e.g., vertex, fragment, geometry, ...). + // + char const* vertexEntryPointName = "vertexMain"; + char const* fragmentEntryPointName = "fragmentMain"; + int vertexIndex = spAddEntryPoint(slangRequest, translationUnitIndex, vertexEntryPointName, SLANG_STAGE_VERTEX); + int fragmentIndex = spAddEntryPoint(slangRequest, translationUnitIndex, fragmentEntryPointName, SLANG_STAGE_FRAGMENT); + + // Once all of the input options for hte compiler have been specified, + // we can invoke `spCompile` to run the compiler and see if any errors + // were detected. + // + int compileErr = spCompile(slangRequest); + + // Even if there were no errors that forced compilation to fail, the + // compiler may have produced "diagnostic" output such as warnings. + // We will go ahead and print that output here. + // + if(auto diagnostics = spGetDiagnosticOutput(slangRequest)) + { + reportError("%s", diagnostics); + } + + // If compilation failed, there is no point in continuing any further. + if(compileErr) + { + spDestroyCompileRequest(slangRequest); + spDestroySession(slangSession); + return nullptr; + } + + // If compilation was successful, then we will extract the code for + // our two entry points as "blobs". + // + // If you are using a D3D API, then your application may want to + // take advantage of the fact taht these blobs are binary compatible + // with the `ID3DBlob`, `ID3D10Blob`, etc. interfaces. + + ISlangBlob* vertexShaderBlob = nullptr; + spGetEntryPointCodeBlob(slangRequest, vertexIndex, 0, &vertexShaderBlob); + + ISlangBlob* fragmentShaderBlob = nullptr; + spGetEntryPointCodeBlob(slangRequest, fragmentIndex, 0, &fragmentShaderBlob); + + // We extract the begin/end pointers to the output code buffers + // using operations on the `ISlangBlob` interface. + char const* vertexCode = (char const*) vertexShaderBlob->getBufferPointer(); + char const* vertexCodeEnd = vertexCode + vertexShaderBlob->getBufferSize(); + char const* fragmentCode = (char const*) fragmentShaderBlob->getBufferPointer(); + char const* fragmentCodeEnd = fragmentCode + fragmentShaderBlob->getBufferSize(); + + // Once we have extract the output blobs, it is safe to destroy + // the compile request and even the session. + // + spDestroyCompileRequest(slangRequest); + spDestroySession(slangSession); + + // Now we use the operations of the example graphics API abstraction + // layer to load shader code into the underlying API. + // + // Reminder: this section does not involve the Slang API at all. + // + + ShaderProgram::KernelDesc kernelDescs[] = + { + { StageType::Vertex, vertexCode, vertexCodeEnd}, + { StageType::Fragment, fragmentCode, fragmentCodeEnd}, + }; + + ShaderProgram::Desc programDesc; + programDesc.pipelineType = PipelineType::Graphics; + programDesc.kernels = &kernelDescs[0]; + programDesc.kernelCount = 2; + + ShaderProgram* shaderProgram = renderer->createProgram(programDesc); + + // Once we've used the output blobs from the Slang compiler to initialize + // the API-specific shader program, we can release their memory. + // + vertexShaderBlob->release(); + fragmentShaderBlob->release(); + + return shaderProgram; +} + +// +// The above function shows the core of what is required to use the +// Slang API as a simple compiler (e.g., a drop-in replacement for +// fxc or dxc). +// +// The rest of this file implements an extremely simple rendering application +// that will execute the vertex/fragment shaders loaded with the function +// we have just defined. // +// We will hard-code the size of our rendering window. // +static int gWindowWidth = 1024; +static int gWindowHeight = 768; + // For the purposes of a small example, we will define the vertex data for a // single triangle directly in the source file. It should be easy to extend // this example to load data from an external source, if desired. // - struct Vertex { float position[3]; @@ -45,534 +194,191 @@ struct Vertex }; static const int kVertexCount = 3; -static const Vertex kVertexData[kVertexCount] = { +static const Vertex kVertexData[kVertexCount] = +{ { { 0, 0, 0.5 }, {1, 0, 0} }, { { 0, 1, 0.5 }, {0, 0, 1} }, { { 1, 0, 0.5 }, {0, 1, 0} }, }; +// We will define global variables for the various platform and +// graphics API objects that our application needs: // - -// Global variabels for the various D3D11 API objects to be used for rendering -ID3D11Buffer* dxConstantBuffer; -ID3D11InputLayout* dxInputLayout; -ID3D11Buffer* dxVertexBuffer; -ID3D11VertexShader* dxVertexShader; -ID3D11PixelShader* dxPixelShader; - -// The Slang compiler currently generates HLSL source, so we'll need a utility -// routine (defined later) to translate that into D3D11 shader bytecode. -ID3DBlob* compileHLSLShader( - char const* source, - char const* entryPointName, - char const* dxProfileName); - -// -// 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. +// As a reminder, *none* of these are Slang API objects. All +// of them come from the utility library we are using to simplify +// building an example program. // -HRESULT initialize( ID3D11Device* dxDevice ) +ApplicationContext* gAppContext; +Window* gWindow; +Renderer* gRenderer; +BufferResource* gConstantBuffer; +InputLayout* gInputLayout; +BufferResource* gVertexBuffer; +ShaderProgram* gShaderProgram; +BindingState* gBindingState; + +enum +{ + OKAY, + FAILURE, +}; + +int initialize() { -#if 1 + // Create a window for our application to render into. + WindowDesc windowDesc; + windowDesc.title = "Hello, World!"; + windowDesc.width = gWindowWidth; + windowDesc.height = gWindowHeight; + gWindow = createWindow(windowDesc); + + // Initialize the rendering layer. // - // First, we will load and compile our Slang source code. + // Note: for now we are hard-coding logic to use the + // Direct3D11 back-end for the graphics API abstraction. + // A future version of this example may support multiple + // platforms/APIs. // + gRenderer = createD3D11Renderer(); + Renderer::Desc rendererDesc; + rendererDesc.width = gWindowWidth; + rendererDesc.height = gWindowHeight; + gRenderer->initialize(rendererDesc, getPlatformWindowHandle(gWindow)); - // The argument here is an optional directory where the Slang compiler - // can cache files to speed up compilation of many kernels. - SlangSession* slangSession = spCreateSession(NULL); - - // A compile request represents a single invocation of the compiler, - // to process some inputs and produce outputs (or errors). - SlangCompileRequest* slangRequest = spCreateCompileRequest(slangSession); - - // Instruct Slang to generate code as HLSL - spSetCodeGenTarget(slangRequest, SLANG_HLSL); - - int translationUnitIndex = spAddTranslationUnit(slangRequest, SLANG_SOURCE_LANGUAGE_SLANG, nullptr); - - spAddTranslationUnitSourceFile(slangRequest, translationUnitIndex, "hello.slang"); - - char const* vertexEntryPointName = "vertexMain"; - char const* fragmentEntryPointName = "fragmentMain"; - - char const* vertexProfileName = "vs_4_0"; - char const* fragmentProfileName = "ps_4_0"; - - int vertexIndex = spAddEntryPoint(slangRequest, translationUnitIndex, vertexEntryPointName, spFindProfile(slangSession, vertexProfileName)); - int fragmentIndex = spAddEntryPoint(slangRequest, translationUnitIndex, fragmentEntryPointName, spFindProfile(slangSession, fragmentProfileName)); - - int compileErr = spCompile(slangRequest); - if(auto diagnostics = spGetDiagnosticOutput(slangRequest)) - { - OutputDebugStringA(diagnostics); - fprintf(stderr, "%s", diagnostics); - } - if(compileErr) - { - return E_FAIL; - } - - char const* vertexCode = spGetEntryPointSource(slangRequest, vertexIndex); - char const* fragmentCode = spGetEntryPointSource(slangRequest, fragmentIndex); - - // TODO(tfoley): Query the required constant-buffer size + // Create a constant buffer for passing the model-view-projection matrix. + // + // TODO: A future version of this example will show how to + // use the Slang reflection API to query the required size + // for the data in this constant buffer. + // int constantBufferSize = 16 * sizeof(float); - // Compile the generated HLSL code - ID3DBlob* dxVertexShaderBlob = compileHLSLShader(vertexCode, vertexEntryPointName, vertexProfileName); - if(!dxVertexShaderBlob) return E_FAIL; + BufferResource::Desc constantBufferDesc; + constantBufferDesc.init(constantBufferSize); + constantBufferDesc.setDefaults(Resource::Usage::ConstantBuffer); + constantBufferDesc.cpuAccessFlags = Resource::AccessFlag::Write; - ID3DBlob* dxPixelShaderBlob = compileHLSLShader(fragmentCode, fragmentEntryPointName, fragmentProfileName); - if(!dxPixelShaderBlob) return E_FAIL; + gConstantBuffer = gRenderer->createBufferResource( + Resource::Usage::ConstantBuffer, + constantBufferDesc); + if(!gConstantBuffer) return FAILURE; - HRESULT hr = S_OK; + // Input Assembler (IA) + // Input Layout - D3D11_BUFFER_DESC dxConstantBufferDesc = { 0 }; - dxConstantBufferDesc.ByteWidth = constantBufferSize; - dxConstantBufferDesc.Usage = D3D11_USAGE_DYNAMIC; - dxConstantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - dxConstantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + InputElementDesc inputElements[] = { + {"POSITION", 0, Format::RGB_Float32, offsetof(Vertex, position) }, + {"COLOR", 0, Format::RGB_Float32, offsetof(Vertex, color) }, + }; + gInputLayout = gRenderer->createInputLayout( + &inputElements[0], + 2); + if(!gInputLayout) return FAILURE; - hr = dxDevice->CreateBuffer( - &dxConstantBufferDesc, - NULL, - &dxConstantBuffer); - if(FAILED(hr)) return hr; + // Vertex Buffer - // We clean up the Slang compilation context and result *after* - // we have done the HLSL-to-bytecode compilation, because Slang - // owns the memory allocation for the generated HLSL, and will - // free it when we destroy the compilation result. - spDestroyCompileRequest(slangRequest); - spDestroySession(slangSession); + BufferResource::Desc vertexBufferDesc; + vertexBufferDesc.init(kVertexCount * sizeof(Vertex)); + vertexBufferDesc.setDefaults(Resource::Usage::VertexBuffer); - // Input Assembler (IA) + gVertexBuffer = gRenderer->createBufferResource( + Resource::Usage::VertexBuffer, + vertexBufferDesc, + &kVertexData[0]); + if(!gVertexBuffer) return FAILURE; - // In Slang-generated HLSL, all vertex shader inputs have a semantic - // like: `A0`, `A1`, `A2`, etc., rather than trying to do by-name - // matching. The user is thus responsibile for ensuring that the - // order of their "input element descs" here matches the order - // in which inputs are declared in the shader code. - D3D11_INPUT_ELEMENT_DESC dxInputElements[] = { - {"A", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(Vertex, position), D3D11_INPUT_PER_VERTEX_DATA, 0 }, - {"A", 1, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(Vertex, color), D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }; - hr = dxDevice->CreateInputLayout( - &dxInputElements[0], - 2, - dxVertexShaderBlob->GetBufferPointer(), - dxVertexShaderBlob->GetBufferSize(), - &dxInputLayout); - if(FAILED(hr)) return hr; - - D3D11_BUFFER_DESC dxVertexBufferDesc = { 0 }; - dxVertexBufferDesc.ByteWidth = kVertexCount * sizeof(Vertex); - dxVertexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE; - dxVertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - - D3D11_SUBRESOURCE_DATA dxVertexBufferInitData = { 0 }; - dxVertexBufferInitData.pSysMem = &kVertexData[0]; - - hr = dxDevice->CreateBuffer( - &dxVertexBufferDesc, - &dxVertexBufferInitData, - &dxVertexBuffer); - if(FAILED(hr)) return hr; + // Shaders (VS, PS, ...) - // Vertex Shader (VS) + gShaderProgram = loadShaderProgram(gRenderer); + if(!gShaderProgram) return FAILURE; - hr = dxDevice->CreateVertexShader( - dxVertexShaderBlob->GetBufferPointer(), - dxVertexShaderBlob->GetBufferSize(), - NULL, - &dxVertexShader); - dxVertexShaderBlob->Release(); - if(FAILED(hr)) return hr; + // Resource binding state - // Pixel Shader (PS) + BindingState::Desc bindingStateDesc; + bindingStateDesc.addBufferResource(gConstantBuffer, BindingState::RegisterRange::makeSingle(0)); + gBindingState = gRenderer->createBindingState(bindingStateDesc); + + // Once we've initialized all the graphics API objects, + // it is time to show our application window and start rendering. - hr = dxDevice->CreatePixelShader( - dxPixelShaderBlob->GetBufferPointer(), - dxPixelShaderBlob->GetBufferSize(), - NULL, - &dxPixelShader); - dxPixelShaderBlob->Release(); - if(FAILED(hr)) return hr; -#endif + showWindow(gWindow); - return S_OK; + return OKAY; } -void renderFrame(ID3D11DeviceContext* dxContext) +void renderFrame() { + // Clear our framebuffer (color target only) + // + static const float kClearColor[] = { 0.25, 0.25, 0.25, 1.0 }; + gRenderer->setClearColor(kClearColor); + gRenderer->clearFrame(); + + // We update our constant buffer per-frame, just for the purposes // of the example, but we don't actually load different data // per-frame (we always use an identity projection). - D3D11_MAPPED_SUBRESOURCE mapped; - HRESULT hr = dxContext->Map(dxConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped); - if(!FAILED(hr)) + // + if(float* data = (float*) gRenderer->map(gConstantBuffer, MapFlavor::WriteDiscard)) { - float* data = (float*) mapped.pData; - static const float kIdentity[] = { 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 }; + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 }; memcpy(data, kIdentity, sizeof(kIdentity)); - dxContext->Unmap(dxConstantBuffer, 0); + gRenderer->unmap(gConstantBuffer); } // Input Assembler (IA) - dxContext->IASetInputLayout(dxInputLayout); - dxContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + gRenderer->setInputLayout(gInputLayout); + gRenderer->setPrimitiveTopology(PrimitiveTopology::TriangleList); - UINT dxVertexStride = sizeof(Vertex); - UINT dxVertexBufferOffset = 0; - dxContext->IASetVertexBuffers(0, 1, &dxVertexBuffer, &dxVertexStride, &dxVertexBufferOffset); + UInt vertexStride = sizeof(Vertex); + UInt vertexBufferOffset = 0; + gRenderer->setVertexBuffers(0, 1, &gVertexBuffer, &vertexStride, &vertexBufferOffset); // Vertex Shader (VS) - - dxContext->VSSetShader(dxVertexShader, NULL, 0); - dxContext->VSSetConstantBuffers(0, 1, &dxConstantBuffer); - // Pixel Shader (PS) - dxContext->PSSetShader(dxPixelShader, NULL, 0); - dxContext->VSSetConstantBuffers(0, 1, &dxConstantBuffer); + gRenderer->setShaderProgram(gShaderProgram); + gRenderer->setBindingState(gBindingState); // - dxContext->Draw(3, 0); + gRenderer->draw(3); + + gRenderer->presentFrame(); } void finalize() { + // TODO: Proper cleanup. } +// This "inner" main function is used by the platform abstraction +// layer to deal with differences in how an entry point needs +// to be defined for different platforms. // -// Definition of the HLSL-to-bytecode compilation logic. -// -ID3DBlob* compileHLSLShader( - char const* source, - char const* entryPointName, - char const* dxProfileName ) +void innerMain(ApplicationContext* context) { - // Rather than statically link against the `d3dcompile` library, we - // dynamically load it. - // - // Note: A more realistic application would compile from HLSL text to D3D - // shader bytecode as part of an offline process, rather than doing it - // on-the-fly like this - // - static pD3DCompile D3DCompile_ = nullptr; - if( !D3DCompile_ ) - { - // TODO(tfoley): maybe want to search for one of a few versions of the DLL - HMODULE d3dcompiler = LoadLibraryA("d3dcompiler_47.dll"); - if(!d3dcompiler) - { - fprintf(stderr, "error: failed load 'd3dcompiler_47.dll'\n"); - exit(1); - } - - D3DCompile_ = (pD3DCompile)GetProcAddress(d3dcompiler, "D3DCompile"); - if( !D3DCompile_ ) - { - fprintf(stderr, "error: failed load symbol 'D3DCompile'\n"); - exit(1); - } - } - - // For this example, we turn on debug output, and turn off all - // optimization. A real application would only use these flags - // when shader debugging is needed. - UINT flags = 0; - flags |= D3DCOMPILE_DEBUG; - flags |= D3DCOMPILE_OPTIMIZATION_LEVEL0 | D3DCOMPILE_SKIP_OPTIMIZATION; - - // The `D3DCompile` entry point takes a bunch of parameters, but we - // don't really need most of them for Slang-generated code. - ID3DBlob* dxShaderBlob = nullptr; - ID3DBlob* dxErrorBlob = nullptr; - HRESULT hr = D3DCompile_( - source, - strlen(source), - "slangGeneratedCode", // TODO: proper path for error messages - nullptr, - nullptr, - entryPointName, - dxProfileName, - flags, - 0, - &dxShaderBlob, - &dxErrorBlob); - - // If the HLSL-to-bytecode compilation produced any diagnostic messages - // then we will print them out (whether or not the compilation failed). - if( dxErrorBlob ) - { - OutputDebugStringA( - (char const*)dxErrorBlob->GetBufferPointer()); - dxErrorBlob->Release(); - } - - if( FAILED(hr) ) + if(initialize() != OKAY) { - return nullptr; + exitApplication(context, 1); } - return dxShaderBlob; -} - - -// -// We use a bare-minimum window procedure to get things up and running. -// - -static LRESULT CALLBACK windowProc( - HWND windowHandle, - UINT message, - WPARAM wParam, - LPARAM lParam) -{ - switch (message) + while(dispatchEvents(context)) { - case WM_CLOSE: - PostQuitMessage(0); - return 0; + renderFrame(); } - return DefWindowProcW(windowHandle, message, wParam, lParam); + finalize(); } +// This macro instantiates an appropriate main function to +// invoke the `innerMain` above. // -// Our `WinMain` handles the basic task of getting a window and rendering -// context up and running. There should be nothing suprising or interesting -// here. -// - -int WINAPI WinMain( - HINSTANCE instance, - HINSTANCE /* prevInstance */, - LPSTR /* commandLine */, - int showCommand) -{ - // First we register a window class. - - WNDCLASSEXW windowClassDesc; - windowClassDesc.cbSize = sizeof(windowClassDesc); - windowClassDesc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; - windowClassDesc.lpfnWndProc = &windowProc; - windowClassDesc.cbClsExtra = 0; - windowClassDesc.cbWndExtra = 0; - windowClassDesc.hInstance = instance; - windowClassDesc.hIcon = 0; - windowClassDesc.hCursor = 0; - windowClassDesc.hbrBackground = 0; - windowClassDesc.lpszMenuName = 0; - windowClassDesc.lpszClassName = L"HelloWorld"; - windowClassDesc.hIconSm = 0; - ATOM windowClassAtom = RegisterClassExW(&windowClassDesc); - if(!windowClassAtom) - { - fprintf(stderr, "error: failed to register window class\n"); - return 1; - } - - // Next, we create a window using that window class. - - DWORD windowExtendedStyle = 0; - DWORD windowStyle = 0; - LPWSTR windowName = L"Slang Hello World"; - HWND windowHandle = CreateWindowExW( - windowExtendedStyle, - (LPWSTR)windowClassAtom, - windowName, - windowStyle, - 0, 0, // x, y - gWindowWidth, gWindowHeight, - NULL, // parent - NULL, // menu - instance, - NULL); - if(!windowHandle) - { - fprintf(stderr, "error: failed to create window\n"); - return 1; - } - - - // Rather than statically link against D3D, we load it dynamically. - - HMODULE d3d11 = LoadLibraryA("d3d11.dll"); - if(!d3d11) - { - fprintf(stderr, "error: failed load 'd3d11.dll'\n"); - return 1; - } - - PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN D3D11CreateDeviceAndSwapChain_ = - (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress( - d3d11, - "D3D11CreateDeviceAndSwapChain"); - if(!D3D11CreateDeviceAndSwapChain_) - { - fprintf(stderr, - "error: failed load symbol 'D3D11CreateDeviceAndSwapChain'\n"); - return 1; - } - - // We create our device in debug mode, just so that we can check that the - // example doesn't trigger warnings. - UINT deviceFlags = 0; - deviceFlags |= D3D11_CREATE_DEVICE_DEBUG; - - // We will ask for the highest feature level that can be supported. - - D3D_FEATURE_LEVEL featureLevels[] = { - D3D_FEATURE_LEVEL_11_1, - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, - D3D_FEATURE_LEVEL_9_3, - D3D_FEATURE_LEVEL_9_2, - D3D_FEATURE_LEVEL_9_1, - }; - D3D_FEATURE_LEVEL dxFeatureLevel = D3D_FEATURE_LEVEL_9_1; - - // Our swap chain uses RGBA8 with sRGB, with double buffering. - - DXGI_SWAP_CHAIN_DESC dxSwapChainDesc = { 0 }; - dxSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - dxSwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; - dxSwapChainDesc.SampleDesc.Count = 1; - dxSwapChainDesc.SampleDesc.Quality = 0; - dxSwapChainDesc.BufferCount = 2; - dxSwapChainDesc.OutputWindow = windowHandle; - dxSwapChainDesc.Windowed = TRUE; - dxSwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - dxSwapChainDesc.Flags = 0; - - // On a machine that does not have an up-to-date version of D3D installed, - // the `D3D11CreateDeviceAndSwapChain` call will fail with `E_INVALIDARG` - // if you ask for featuer level 11_1. The workaround is to call - // `D3D11CreateDeviceAndSwapChain` up to twice: the first time with 11_1 - // at the start of the list of requested feature levels, and the second - // time without it. - - IDXGISwapChain* dxSwapChain = NULL; - ID3D11Device* dxDevice = NULL; - ID3D11DeviceContext* dxImmediateContext = NULL; - HRESULT hr = S_OK; - for( int ii = 0; ii < 2; ++ii ) - { - hr = D3D11CreateDeviceAndSwapChain_( - NULL, // adapter (use default) - D3D_DRIVER_TYPE_HARDWARE, - NULL, // software - deviceFlags, - &featureLevels[ii], - (sizeof(featureLevels) / sizeof(featureLevels[0])) - 1, - D3D11_SDK_VERSION, - &dxSwapChainDesc, - &dxSwapChain, - &dxDevice, - &dxFeatureLevel, - &dxImmediateContext); - - // Failures with `E_INVALIDARG` might be due to feature level 11_1 - // not being supported. Other failures are real, though. - if( hr != E_INVALIDARG ) - break; - } - if( FAILED(hr) ) - { - return 1; - } - - // After we've created the swap chain, we can request a pointer to the - // back buffer as a D3D11 texture, and create a render-target view from it. - - ID3D11Texture2D* dxBackBufferTexture = NULL; - static const IID kIID_ID3D11Texture2D = { - 0x6f15aaf2, 0xd208, 0x4e89, 0x9a, 0xb4, 0x48, - 0x95, 0x35, 0xd3, 0x4f, 0x9c }; - dxSwapChain->GetBuffer( - 0, - kIID_ID3D11Texture2D, - (void**)&dxBackBufferTexture); - - ID3D11RenderTargetView* dxBackBufferRTV = NULL; - dxDevice->CreateRenderTargetView( - dxBackBufferTexture, - NULL, - &dxBackBufferRTV); - - // We immediately bind the back-buffer render target view, and we aren't - // going to switch. We don't bother with a depth buffer. - dxImmediateContext->OMSetRenderTargets( - 1, - &dxBackBufferRTV, - NULL); - - // Similarly, we are going to set up a viewport once, and then never - // switch, since this is a simple test app. - D3D11_VIEWPORT dxViewport; - dxViewport.TopLeftX = 0; - dxViewport.TopLeftY = 0; - dxViewport.Width = (float) gWindowWidth; - dxViewport.Height = (float) gWindowHeight; - dxViewport.MaxDepth = 1; // TODO(tfoley): use reversed depth - dxViewport.MinDepth = 0; - dxImmediateContext->RSSetViewports(1, &dxViewport); - - // Once we've done the general-purpose initialization, we - // initialize anything specific to the "hello world" application - hr = initialize( dxDevice ); - if( FAILED(hr) ) - { - exit(1); - } - - // 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 }; - dxImmediateContext->ClearRenderTargetView( - dxBackBufferRTV, - kClearColor); - - renderFrame( dxImmediateContext ); - - dxSwapChain->Present(0, 0); - } - } - - return 0; -} +SG_UI_MAIN(innerMain) diff --git a/examples/hello/hello.slang b/examples/hello/hello.slang index f495d12b4..5a68979ce 100644 --- a/examples/hello/hello.slang +++ b/examples/hello/hello.slang @@ -1,24 +1,28 @@ // hello.slang +// This file provides a simple vertex and fragment shader that can be compiled +// using Slang. This code should also be valid as HLSL, and thus it does not +// use any of the new language features supported by Slang. + cbuffer Uniforms { - float4x4 modelViewProjection; + float4x4 modelViewProjection; } struct AssembledVertex { - float3 position; - float3 color; + float3 position : POSITION; + float3 color : COLOR; }; struct CoarseVertex { - float3 color; + float3 color; }; struct Fragment { - float4 color; + float4 color; }; @@ -26,48 +30,47 @@ struct Fragment struct VertexStageInput { - AssembledVertex assembledVertex : A; + AssembledVertex assembledVertex; }; struct VertexStageOutput { - CoarseVertex coarseVertex : CoarseVertex; - float4 sv_position : SV_Position; + CoarseVertex coarseVertex : CoarseVertex; + float4 sv_position : SV_Position; }; VertexStageOutput vertexMain(VertexStageInput input) { - VertexStageOutput output; + VertexStageOutput output; - float3 position = input.assembledVertex.position; - float3 color = input.assembledVertex.color; + float3 position = input.assembledVertex.position; + float3 color = input.assembledVertex.color; - output.coarseVertex.color = color; - output.sv_position = mul(modelViewProjection, float4(position, 1.0)); + output.coarseVertex.color = color; + output.sv_position = mul(modelViewProjection, float4(position, 1.0)); - return output; + return output; } // Fragment Shader struct FragmentStageInput { - CoarseVertex coarseVertex : CoarseVertex; + CoarseVertex coarseVertex : CoarseVertex; }; struct FragmentStageOutput { - Fragment fragment : SV_Target; + Fragment fragment : SV_Target; }; FragmentStageOutput fragmentMain(FragmentStageInput input) { - FragmentStageOutput output; + FragmentStageOutput output; - float3 color = input.coarseVertex.color; + float3 color = input.coarseVertex.color; - output.fragment.color = float4(color, 1.0); + output.fragment.color = float4(color, 1.0); - return output; + return output; } - diff --git a/examples/hello/hello.vcxproj b/examples/hello/hello.vcxproj index 72bedbd72..885c2ff86 100644 --- a/examples/hello/hello.vcxproj +++ b/examples/hello/hello.vcxproj @@ -98,7 +98,7 @@ <PrecompiledHeader>NotUsing</PrecompiledHeader> <WarningLevel>Level3</WarningLevel> <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>..\..;..\..\tools;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <DebugInformationFormat>EditAndContinue</DebugInformationFormat> <Optimization>Disabled</Optimization> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> @@ -113,7 +113,7 @@ <PrecompiledHeader>NotUsing</PrecompiledHeader> <WarningLevel>Level3</WarningLevel> <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>..\..;..\..\tools;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <DebugInformationFormat>EditAndContinue</DebugInformationFormat> <Optimization>Disabled</Optimization> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> @@ -128,7 +128,7 @@ <PrecompiledHeader>NotUsing</PrecompiledHeader> <WarningLevel>Level3</WarningLevel> <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>..\..;..\..\tools;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <Optimization>Full</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> @@ -147,7 +147,7 @@ <PrecompiledHeader>NotUsing</PrecompiledHeader> <WarningLevel>Level3</WarningLevel> <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>..\..;..\..\tools;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <Optimization>Full</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> @@ -171,6 +171,12 @@ <ProjectReference Include="..\..\source\slang\slang.vcxproj"> <Project>{DB00DA62-0533-4AFD-B59F-A67D5B3A0808}</Project> </ProjectReference> + <ProjectReference Include="..\..\source\core\core.vcxproj"> + <Project>{F9BE7957-8399-899E-0C49-E714FDDD4B65}</Project> + </ProjectReference> + <ProjectReference Include="..\..\tools\slang-graphics\slang-graphics.vcxproj"> + <Project>{222F7498-B40C-4F3F-A704-DDEB91A4484A}</Project> + </ProjectReference> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> diff --git a/premake5.lua b/premake5.lua index 9bb41e71b..2953922b2 100644 --- a/premake5.lua +++ b/premake5.lua @@ -266,6 +266,8 @@ end -- example "hello" uuid "E6385042-1649-4803-9EBD-168F8B7EF131" + includedirs { ".", "tools" } + links { "core", "slang-graphics" } -- -- Note how we are calling our custom `example()` subroutine with -- the same syntax sugar that Premake usually advocates for their @@ -300,7 +302,6 @@ standardProject "core" warnings "Extra" flags { "FatalWarnings" } - -- -- `slang-generate` is a tool we use for source code generation on -- the compiler. It depends on the `core` library, so we need to @@ -363,8 +364,31 @@ tool "slang-eval-test" tool "render-test" uuid "96610759-07B9-4EEB-A974-5C634A2E742B" + includedirs { ".", "external", "source", "tools/slang-graphics" } + links { "core", "slang", "slang-graphics" } + filter { "system:windows" } + + systemversion "10.0.14393.0" + + -- For Windows targets, we want to copy d3dcompiler_47.dll, + -- dxcompiler.dll, and dxil.dll from the Windows SDK redistributable + -- directory into the output directory. + postbuildcommands { '"$(SolutionDir)tools\\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/%{cfg.platform:lower()}/" "%{cfg.targetdir}/"'} + +-- +-- `slang-graphics` is a utility library for doing GPU rendering +-- and compute, which is used by both our testing and exmaples. +-- It depends on teh `core` library, so we need to declare that: +-- + +tool "slang-graphics" + uuid "222F7498-B40C-4F3F-A704-DDEB91A4484A" + -- Unlike most of the code under `tools/`, this is a library + -- rather than a stand-alone executable. + kind "StaticLib" + includedirs { ".", "external", "source" } - links { "core", "slang" } + filter { "system:windows" } systemversion "10.0.14393.0" @@ -374,6 +398,8 @@ tool "render-test" -- directory into the output directory. postbuildcommands { '"$(SolutionDir)tools\\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/%{cfg.platform:lower()}/" "%{cfg.targetdir}/"'} + + -- -- The `slangc` command-line application is just a very thin wrapper -- around the Slang dynamic library, so its build is extermely simple. @@ -19,6 +19,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slang-eval-test", "tools\sl EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "render-test", "tools\render-test\render-test.vcxproj", "{96610759-07B9-4EEB-A974-5C634A2E742B}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slang-graphics", "tools\slang-graphics\slang-graphics.vcxproj", "{222F7498-B40C-4F3F-A704-DDEB91A4484A}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slangc", "source\slangc\slangc.vcxproj", "{D56CBCEB-1EB5-4CA8-AEC4-48EA35ED61C7}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slang", "source\slang\slang.vcxproj", "{DB00DA62-0533-4AFD-B59F-A67D5B3A0808}" @@ -92,6 +94,14 @@ Global {96610759-07B9-4EEB-A974-5C634A2E742B}.Release|Win32.Build.0 = Release|Win32 {96610759-07B9-4EEB-A974-5C634A2E742B}.Release|x64.ActiveCfg = Release|x64 {96610759-07B9-4EEB-A974-5C634A2E742B}.Release|x64.Build.0 = Release|x64 + {222F7498-B40C-4F3F-A704-DDEB91A4484A}.Debug|Win32.ActiveCfg = Debug|Win32 + {222F7498-B40C-4F3F-A704-DDEB91A4484A}.Debug|Win32.Build.0 = Debug|Win32 + {222F7498-B40C-4F3F-A704-DDEB91A4484A}.Debug|x64.ActiveCfg = Debug|x64 + {222F7498-B40C-4F3F-A704-DDEB91A4484A}.Debug|x64.Build.0 = Debug|x64 + {222F7498-B40C-4F3F-A704-DDEB91A4484A}.Release|Win32.ActiveCfg = Release|Win32 + {222F7498-B40C-4F3F-A704-DDEB91A4484A}.Release|Win32.Build.0 = Release|Win32 + {222F7498-B40C-4F3F-A704-DDEB91A4484A}.Release|x64.ActiveCfg = Release|x64 + {222F7498-B40C-4F3F-A704-DDEB91A4484A}.Release|x64.Build.0 = Release|x64 {D56CBCEB-1EB5-4CA8-AEC4-48EA35ED61C7}.Debug|Win32.ActiveCfg = Debug|Win32 {D56CBCEB-1EB5-4CA8-AEC4-48EA35ED61C7}.Debug|Win32.Build.0 = Debug|Win32 {D56CBCEB-1EB5-4CA8-AEC4-48EA35ED61C7}.Debug|x64.ActiveCfg = Debug|x64 @@ -127,5 +137,6 @@ Global {22C45F4F-FB6B-4535-BED1-D3F5D0C71047} = {FD47AE19-69FD-260F-F2F1-20E65EA61D13} {205FCAB9-A13F-4980-86FA-F6221A7095EE} = {FD47AE19-69FD-260F-F2F1-20E65EA61D13} {96610759-07B9-4EEB-A974-5C634A2E742B} = {FD47AE19-69FD-260F-F2F1-20E65EA61D13} + {222F7498-B40C-4F3F-A704-DDEB91A4484A} = {FD47AE19-69FD-260F-F2F1-20E65EA61D13} EndGlobalSection EndGlobal diff --git a/tools/render-test/options.h b/tools/render-test/options.h index a14acec15..82c018f66 100644 --- a/tools/render-test/options.h +++ b/tools/render-test/options.h @@ -9,6 +9,8 @@ namespace renderer_test { +using namespace slang_graphics; + struct Options { enum @@ -25,7 +27,7 @@ struct Options // Raw HLSL or GLSL input, bypassing Slang Native, }; - + enum class ShaderProgramType { diff --git a/tools/render-test/png-serialize-util.h b/tools/render-test/png-serialize-util.h index fe3b4f873..dad17ae74 100644 --- a/tools/render-test/png-serialize-util.h +++ b/tools/render-test/png-serialize-util.h @@ -2,10 +2,12 @@ #pragma once #include "surface.h" - + namespace renderer_test { -struct PngSerializeUtil +using namespace slang_graphics; + +struct PngSerializeUtil { static Slang::Result write(const char* filename, const Surface& surface); diff --git a/tools/render-test/render-test.vcxproj b/tools/render-test/render-test.vcxproj index 915d0d753..66ad9e7ed 100644 --- a/tools/render-test/render-test.vcxproj +++ b/tools/render-test/render-test.vcxproj @@ -99,7 +99,7 @@ <PrecompiledHeader>NotUsing</PrecompiledHeader> <WarningLevel>Level3</WarningLevel> <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..\..;..\..\external;..\..\source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>..\..;..\..\external;..\..\source;..\slang-graphics;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <DebugInformationFormat>EditAndContinue</DebugInformationFormat> <Optimization>Disabled</Optimization> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> @@ -117,7 +117,7 @@ <PrecompiledHeader>NotUsing</PrecompiledHeader> <WarningLevel>Level3</WarningLevel> <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..\..;..\..\external;..\..\source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>..\..;..\..\external;..\..\source;..\slang-graphics;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <DebugInformationFormat>EditAndContinue</DebugInformationFormat> <Optimization>Disabled</Optimization> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> @@ -135,7 +135,7 @@ <PrecompiledHeader>NotUsing</PrecompiledHeader> <WarningLevel>Level3</WarningLevel> <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..\..;..\..\external;..\..\source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>..\..;..\..\external;..\..\source;..\slang-graphics;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <Optimization>Full</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> @@ -157,7 +157,7 @@ <PrecompiledHeader>NotUsing</PrecompiledHeader> <WarningLevel>Level3</WarningLevel> <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..\..;..\..\external;..\..\source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>..\..;..\..\external;..\..\source;..\slang-graphics;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <Optimization>Full</Optimization> <FunctionLevelLinking>true</FunctionLevelLinking> <IntrinsicFunctions>true</IntrinsicFunctions> @@ -175,50 +175,19 @@ </PostBuildEvent> </ItemDefinitionGroup> <ItemGroup> - <ClInclude Include="circular-resource-heap-d3d12.h" /> - <ClInclude Include="d3d-util.h" /> - <ClInclude Include="descriptor-heap-d3d12.h" /> <ClInclude Include="options.h" /> <ClInclude Include="png-serialize-util.h" /> - <ClInclude Include="render-d3d11.h" /> - <ClInclude Include="render-d3d12.h" /> - <ClInclude Include="render-gl.h" /> - <ClInclude Include="render-vk.h" /> - <ClInclude Include="render.h" /> - <ClInclude Include="resource-d3d12.h" /> <ClInclude Include="shader-input-layout.h" /> <ClInclude Include="shader-renderer-util.h" /> <ClInclude Include="slang-support.h" /> - <ClInclude Include="surface.h" /> - <ClInclude Include="vk-api.h" /> - <ClInclude Include="vk-device-queue.h" /> - <ClInclude Include="vk-module.h" /> - <ClInclude Include="vk-swap-chain.h" /> - <ClInclude Include="vk-util.h" /> - <ClInclude Include="window.h" /> </ItemGroup> <ItemGroup> - <ClCompile Include="circular-resource-heap-d3d12.cpp" /> - <ClCompile Include="d3d-util.cpp" /> - <ClCompile Include="descriptor-heap-d3d12.cpp" /> <ClCompile Include="main.cpp" /> <ClCompile Include="options.cpp" /> <ClCompile Include="png-serialize-util.cpp" /> - <ClCompile Include="render-d3d11.cpp" /> - <ClCompile Include="render-d3d12.cpp" /> - <ClCompile Include="render-gl.cpp" /> - <ClCompile Include="render-vk.cpp" /> - <ClCompile Include="render.cpp" /> - <ClCompile Include="resource-d3d12.cpp" /> <ClCompile Include="shader-input-layout.cpp" /> <ClCompile Include="shader-renderer-util.cpp" /> <ClCompile Include="slang-support.cpp" /> - <ClCompile Include="surface.cpp" /> - <ClCompile Include="vk-api.cpp" /> - <ClCompile Include="vk-device-queue.cpp" /> - <ClCompile Include="vk-module.cpp" /> - <ClCompile Include="vk-swap-chain.cpp" /> - <ClCompile Include="vk-util.cpp" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\..\source\core\core.vcxproj"> @@ -227,6 +196,9 @@ <ProjectReference Include="..\..\source\slang\slang.vcxproj"> <Project>{DB00DA62-0533-4AFD-B59F-A67D5B3A0808}</Project> </ProjectReference> + <ProjectReference Include="..\slang-graphics\slang-graphics.vcxproj"> + <Project>{222F7498-B40C-4F3F-A704-DDEB91A4484A}</Project> + </ProjectReference> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> diff --git a/tools/render-test/render-test.vcxproj.filters b/tools/render-test/render-test.vcxproj.filters index b2f48a397..ff3d52a7e 100644 --- a/tools/render-test/render-test.vcxproj.filters +++ b/tools/render-test/render-test.vcxproj.filters @@ -9,39 +9,12 @@ </Filter> </ItemGroup> <ItemGroup> - <ClInclude Include="circular-resource-heap-d3d12.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="d3d-util.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="descriptor-heap-d3d12.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="options.h"> <Filter>Header Files</Filter> </ClInclude> <ClInclude Include="png-serialize-util.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="render-d3d11.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="render-d3d12.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="render-gl.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="render-vk.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="render.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="resource-d3d12.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="shader-input-layout.h"> <Filter>Header Files</Filter> </ClInclude> @@ -51,38 +24,8 @@ <ClInclude Include="slang-support.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="surface.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="vk-api.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="vk-device-queue.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="vk-module.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="vk-swap-chain.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="vk-util.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="window.h"> - <Filter>Header Files</Filter> - </ClInclude> </ItemGroup> <ItemGroup> - <ClCompile Include="circular-resource-heap-d3d12.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="d3d-util.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="descriptor-heap-d3d12.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="main.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -92,24 +35,6 @@ <ClCompile Include="png-serialize-util.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="render-d3d11.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="render-d3d12.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="render-gl.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="render-vk.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="render.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="resource-d3d12.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="shader-input-layout.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -119,23 +44,5 @@ <ClCompile Include="slang-support.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="surface.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="vk-api.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="vk-device-queue.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="vk-module.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="vk-swap-chain.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="vk-util.cpp"> - <Filter>Source Files</Filter> - </ClCompile> </ItemGroup> </Project>
\ No newline at end of file diff --git a/tools/render-test/shader-input-layout.h b/tools/render-test/shader-input-layout.h index 7537527ab..19a7e59d0 100644 --- a/tools/render-test/shader-input-layout.h +++ b/tools/render-test/shader-input-layout.h @@ -7,6 +7,8 @@ namespace renderer_test { +using namespace slang_graphics; + enum class ShaderInputType { Buffer, Texture, Sampler, CombinedTextureSampler diff --git a/tools/render-test/window.h b/tools/render-test/window.h deleted file mode 100644 index 5d0a89ee4..000000000 --- a/tools/render-test/window.h +++ /dev/null @@ -1,10 +0,0 @@ -// window.h -#pragma once - -namespace renderer_test { - -typedef struct Window Window; - -Window* createWindow(); - -} // renderer_test diff --git a/tools/render-test/circular-resource-heap-d3d12.cpp b/tools/slang-graphics/circular-resource-heap-d3d12.cpp index ae8e13822..8b63819a5 100644 --- a/tools/render-test/circular-resource-heap-d3d12.cpp +++ b/tools/slang-graphics/circular-resource-heap-d3d12.cpp @@ -1,6 +1,6 @@ #include "circular-resource-heap-d3d12.h" -namespace renderer_test { +namespace slang_graphics { using namespace Slang; D3D12CircularResourceHeap::D3D12CircularResourceHeap(): @@ -24,8 +24,8 @@ void D3D12CircularResourceHeap::_freeBlockListResources(const Block* start) { if (start) { - const Block* block = start; - do + const Block* block = start; + do { ID3D12Resource* resource = block->m_resource; @@ -36,12 +36,12 @@ void D3D12CircularResourceHeap::_freeBlockListResources(const Block* start) block = block->m_next; } while (block != start); - } + } } Result D3D12CircularResourceHeap::init(ID3D12Device* device, const Desc& desc, D3D12CounterFence* fence) { - assert(m_blocks == nullptr); + assert(m_blocks == nullptr); assert(desc.m_blockSize > 0); m_fence = fence; @@ -57,14 +57,14 @@ void D3D12CircularResourceHeap::addSync(uint64_t signalValue) PendingEntry entry; entry.m_completedValue = signalValue; entry.m_cursor = m_front; - m_pendingQueue.Add(entry); + m_pendingQueue.Add(entry); } void D3D12CircularResourceHeap::updateCompleted() { const uint64_t completedValue = m_fence->getCompletedValue(); - -#if 0 + +#if 0 while (m_pendingQueue.Count() != 0) { const PendingEntry& entry = m_pendingQueue[0]; @@ -170,7 +170,7 @@ D3D12CircularResourceHeap::Cursor D3D12CircularResourceHeap::allocate(size_t siz m_front = m_back; } - // If front and back are in the same block then front MUST be ahead of back (as that defined as + // If front and back are in the same block then front MUST be ahead of back (as that defined as // an invariant and is required for block insertion to be possible Block* block = m_front.m_block; @@ -191,7 +191,7 @@ D3D12CircularResourceHeap::Cursor D3D12CircularResourceHeap::allocate(size_t siz } // Okay I can't fit into current block... - + // If the next block contains front, we need to add a block, else we can use that block if (block->m_next == m_back.m_block) { @@ -200,7 +200,7 @@ D3D12CircularResourceHeap::Cursor D3D12CircularResourceHeap::allocate(size_t siz newBlock->m_next = block->m_next; block->m_next = newBlock; } - + // Use the block we are going to add to block = block->m_next; uint8_t* cur = (uint8_t*)((size_t(block->m_start) + alignment - 1) & ~(alignment - 1)); @@ -219,4 +219,4 @@ D3D12CircularResourceHeap::Cursor D3D12CircularResourceHeap::allocate(size_t siz return cursor; } -} // namespace renderer_test +} // namespace slang_graphics diff --git a/tools/render-test/circular-resource-heap-d3d12.h b/tools/slang-graphics/circular-resource-heap-d3d12.h index baa9a9b0c..a200d3bbc 100644 --- a/tools/render-test/circular-resource-heap-d3d12.h +++ b/tools/slang-graphics/circular-resource-heap-d3d12.h @@ -6,25 +6,25 @@ #include "resource-d3d12.h" -namespace renderer_test { - -/*! \brief The D3D12CircularResourceHeap is a heap that is suited for size constrained real-time resources allocation that -is transitory in nature. It is designed to allocate resources which are used and discarded, often used where in -previous versions of DirectX the 'DISCARD' flag was used. - -The idea is to have a heap which chunks of resource can be allocated, and used for GPU execution, -and that the heap is able through the addSync/updateCompleted idiom is able to track when the usage of the resources is -completed allowing them to be reused. The heap is arranged as circularly, with new allocations made from the front, and the back -being updated as the GPU updating the back when it is informed anything using prior parts of the heap have completed. In this -arrangement all the heap between the back and the front can be thought of as in use or potentially in use by the GPU. All the heap -from the front back around to the back, is free and can be allocated from. It is the responsibility of the user of the Heap to make -sure the invariant holds, but in most normal usage it does so simply. - -Another feature of the heap is that it does not require upfront knowledge of how big a heap is needed. The backing resources will be expanded -dynamically with requests as needed. The only requirement is that know single request can be larger than m_blockSize specified in the Desc +namespace slang_graphics { + +/*! \brief The D3D12CircularResourceHeap is a heap that is suited for size constrained real-time resources allocation that +is transitory in nature. It is designed to allocate resources which are used and discarded, often used where in +previous versions of DirectX the 'DISCARD' flag was used. + +The idea is to have a heap which chunks of resource can be allocated, and used for GPU execution, +and that the heap is able through the addSync/updateCompleted idiom is able to track when the usage of the resources is +completed allowing them to be reused. The heap is arranged as circularly, with new allocations made from the front, and the back +being updated as the GPU updating the back when it is informed anything using prior parts of the heap have completed. In this +arrangement all the heap between the back and the front can be thought of as in use or potentially in use by the GPU. All the heap +from the front back around to the back, is free and can be allocated from. It is the responsibility of the user of the Heap to make +sure the invariant holds, but in most normal usage it does so simply. + +Another feature of the heap is that it does not require upfront knowledge of how big a heap is needed. The backing resources will be expanded +dynamically with requests as needed. The only requirement is that know single request can be larger than m_blockSize specified in the Desc used to initialize the heap. This is because all the backing resources are allocated to a single size. This limitation means the D3D12CircularResourceHeap -may not be the best use for example for uploading a texture - because it's design is really around transitory uploads or write backs, and so more suited -to constant buffers, vertex buffer, index buffers and the like. +may not be the best use for example for uploading a texture - because it's design is really around transitory uploads or write backs, and so more suited +to constant buffers, vertex buffer, index buffers and the like. To upload a texture at program startup it is most likely better to use a D3D12ResourceScopeManager. @@ -35,7 +35,7 @@ typedef D3D12CircularResourceHeap Heap; Heap::Cursor cursor = heap.allocateVertexBuffer(sizeof(Vertex) * numVerts); Memory:copy(cursor.m_position, verts, sizeof(Vertex) * numVerts); -// Do a command using the GPU handle +// Do a command using the GPU handle m_commandList->... // Do another command using the GPU handle @@ -66,7 +66,7 @@ new blocks in front of front. So it must be possible to do an block insertion be |--B---F-----| |----------| When B and F are on top of one another it means there is nothing in the list. NOTE this also means that a move of front can never place it -top of the back. +top of the back. https://msdn.microsoft.com/en-us/library/windows/desktop/dn899125%28v=vs.85%29.aspx https://msdn.microsoft.com/en-us/library/windows/desktop/mt426646%28v=vs.85%29.aspx @@ -79,18 +79,18 @@ class D3D12CircularResourceHeap public: typedef D3D12CircularResourceHeap ThisType; - /// The alignment used for VERTEX_BUFFER allocations + /// The alignment used for VERTEX_BUFFER allocations /// Strictly speaking it seems the hardware can handle 4 byte alignment, but since often in use /// data will be copied from CPU memory to the allocation, using 16 byte alignment is superior as allows /// significantly faster memcpy. /// The sample that shows sizeof(float) - 4 bytes is appropriate is at the link below. /// https://msdn.microsoft.com/en-us/library/windows/desktop/mt426646%28v=vs.85%29.aspx - enum + enum { VERTEX_BUFFER_ALIGNMENT = 16, }; - struct Desc + struct Desc { void init() { @@ -117,7 +117,7 @@ class D3D12CircularResourceHeap /// Cursor position struct Cursor { - /// Get GpuHandle + /// Get GpuHandle SLANG_FORCE_INLINE D3D12_GPU_VIRTUAL_ADDRESS getGpuHandle() const { return m_block->m_resource->GetGPUVirtualAddress() + size_t(m_position - m_block->m_start); } /// Must have a block and position SLANG_FORCE_INLINE bool isValid() const { return m_block != nullptr; } @@ -135,11 +135,11 @@ class D3D12CircularResourceHeap /// Must be called before used /// Block size must be at least as large as the _largest_ thing allocated - /// Also note depending on alignment of a resource allocation, the block size might also need to take into account the - /// maximum alignment use. It is a REQUIREMENT that a newly allocated resource block is large enough to hold any + /// Also note depending on alignment of a resource allocation, the block size might also need to take into account the + /// maximum alignment use. It is a REQUIREMENT that a newly allocated resource block is large enough to hold any /// allocation taking into account the alignment used. Slang::Result init(ID3D12Device* device, const Desc& desc, D3D12CounterFence* fence); - + /// Get the block size SLANG_FORCE_INLINE size_t getBlockSize() const { return m_desc.m_blockSize; } @@ -153,7 +153,7 @@ class D3D12CircularResourceHeap /// Create filled in constant buffer SLANG_FORCE_INLINE Cursor newConstantBuffer(const void* data, size_t size) { Cursor cursor = allocateConstantBuffer(size); ::memcpy(cursor.m_position, data, size); return cursor; } - /// Create in filled in constant buffer + /// Create in filled in constant buffer template <typename T> SLANG_FORCE_INLINE Cursor newConstantBuffer(const T& in) { return newConstantBuffer(&in, sizeof(T)); } @@ -172,12 +172,12 @@ class D3D12CircularResourceHeap ~D3D12CircularResourceHeap(); protected: - + struct Block { ID3D12Resource* m_resource; ///< The mapped resource uint8_t* m_start; ///< Once created the resource is mapped to here - Block* m_next; ///< Points to next block in the list + Block* m_next; ///< Points to next block in the list }; struct PendingEntry { @@ -193,14 +193,14 @@ class D3D12CircularResourceHeap Slang::List<PendingEntry> m_pendingQueue; ///< Holds the list of pending positions. When the fence value is greater than the value on the queue entry, the entry is done. // Allocation is made from the front, and freed from the back. - Cursor m_back; ///< Current back position. - Cursor m_front; ///< Current front position. - + Cursor m_back; ///< Current back position. + Cursor m_front; ///< Current front position. + Desc m_desc; ///< Describes the heap D3D12CounterFence* m_fence; ///< The fence to use ID3D12Device* m_device; ///< The device that resources will be constructed on }; -} // namespace renderer_test +} // namespace slang_graphics diff --git a/tools/render-test/d3d-util.cpp b/tools/slang-graphics/d3d-util.cpp index 08aa563ca..b2c3f87ee 100644 --- a/tools/render-test/d3d-util.cpp +++ b/tools/slang-graphics/d3d-util.cpp @@ -6,7 +6,7 @@ // We will use the C standard library just for printing error messages. #include <stdio.h> -namespace renderer_test { +namespace slang_graphics { using namespace Slang; /* static */D3D_PRIMITIVE_TOPOLOGY D3DUtil::getPrimitiveTopology(PrimitiveTopology topology) diff --git a/tools/render-test/d3d-util.h b/tools/slang-graphics/d3d-util.h index b7a268fd8..b5f154e6e 100644 --- a/tools/render-test/d3d-util.h +++ b/tools/slang-graphics/d3d-util.h @@ -13,7 +13,7 @@ #include <D3Dcommon.h> #include <DXGIFormat.h> -namespace renderer_test { +namespace slang_graphics { class D3DUtil { diff --git a/tools/render-test/descriptor-heap-d3d12.cpp b/tools/slang-graphics/descriptor-heap-d3d12.cpp index 5bd238528..23c56d46d 100644 --- a/tools/render-test/descriptor-heap-d3d12.cpp +++ b/tools/slang-graphics/descriptor-heap-d3d12.cpp @@ -1,7 +1,7 @@ #include "descriptor-heap-d3d12.h" -namespace renderer_test { +namespace slang_graphics { using namespace Slang; D3D12DescriptorHeap::D3D12DescriptorHeap(): @@ -30,7 +30,7 @@ Result D3D12DescriptorHeap::init(ID3D12Device* device, const D3D12_CPU_DESCRIPTO SLANG_RETURN_ON_FAIL(init(device, numHandles, type, flags)); D3D12_CPU_DESCRIPTOR_HANDLE dst = m_heap->GetCPUDescriptorHandleForHeapStart(); - // Copy them all + // Copy them all for (int i = 0; i < numHandles; i++, dst.ptr += m_descriptorSize) { D3D12_CPU_DESCRIPTOR_HANDLE src = handles[i]; @@ -43,5 +43,5 @@ Result D3D12DescriptorHeap::init(ID3D12Device* device, const D3D12_CPU_DESCRIPTO return SLANG_OK; } -} // namespace renderer_test +} // namespace slang_graphics diff --git a/tools/render-test/descriptor-heap-d3d12.h b/tools/slang-graphics/descriptor-heap-d3d12.h index 1d0302d2c..6ddb583dc 100644 --- a/tools/render-test/descriptor-heap-d3d12.h +++ b/tools/slang-graphics/descriptor-heap-d3d12.h @@ -6,7 +6,7 @@ #include "../../slang-com-ptr.h" -namespace renderer_test { +namespace slang_graphics { /*! \brief A simple class to manage an underlying Dx12 Descriptor Heap. Allocations are made linearly in order. It is not possible to free individual allocations, but all allocations can be deallocated with 'deallocateAll'. */ @@ -30,13 +30,13 @@ class D3D12DescriptorHeap /// Allocate a number of descriptors. Returns the start index (or -1 if not possible) SLANG_FORCE_INLINE int allocate(int numDescriptors); - /// + /// SLANG_FORCE_INLINE int placeAt(int index); /// Deallocates all allocations, and starts allocation from the start of the underlying heap again SLANG_FORCE_INLINE void deallocateAll() { m_currentIndex = 0; } - /// Get the size of each + /// Get the size of each SLANG_FORCE_INLINE int getDescriptorSize() const { return m_descriptorSize; } /// Get the GPU heap start @@ -68,7 +68,7 @@ int D3D12DescriptorHeap::allocate() assert(m_currentIndex < m_totalSize); if (m_currentIndex < m_totalSize) { - return m_currentIndex++; + return m_currentIndex++; } return -1; } @@ -94,22 +94,22 @@ SLANG_FORCE_INLINE int D3D12DescriptorHeap::placeAt(int index) // --------------------------------------------------------------------------- SLANG_FORCE_INLINE D3D12_CPU_DESCRIPTOR_HANDLE D3D12DescriptorHeap::getCpuHandle(int index) const -{ - assert(index >= 0 && index < m_totalSize); +{ + assert(index >= 0 && index < m_totalSize); D3D12_CPU_DESCRIPTOR_HANDLE start = m_heap->GetCPUDescriptorHandleForHeapStart(); D3D12_CPU_DESCRIPTOR_HANDLE dst; dst.ptr = start.ptr + m_descriptorSize * index; return dst; -} +} // --------------------------------------------------------------------------- SLANG_FORCE_INLINE D3D12_GPU_DESCRIPTOR_HANDLE D3D12DescriptorHeap::getGpuHandle(int index) const -{ - assert(index >= 0 && index < m_totalSize); +{ + assert(index >= 0 && index < m_totalSize); D3D12_GPU_DESCRIPTOR_HANDLE start = m_heap->GetGPUDescriptorHandleForHeapStart(); D3D12_GPU_DESCRIPTOR_HANDLE dst; dst.ptr = start.ptr + m_descriptorSize * index; return dst; } -} // namespace renderer_test +} // namespace slang_graphics diff --git a/tools/render-test/render-d3d11.cpp b/tools/slang-graphics/render-d3d11.cpp index 109c5aca1..4f9749e39 100644 --- a/tools/render-test/render-d3d11.cpp +++ b/tools/slang-graphics/render-d3d11.cpp @@ -4,7 +4,7 @@ #include "render-d3d11.h" -#include "options.h" +//WORKING: #include "options.h" #include "render.h" #include "d3d-util.h" @@ -12,7 +12,7 @@ // In order to use the Slang API, we need to include its header -#include <slang.h> +//#include <slang.h> #include "../../slang-com-ptr.h" @@ -40,7 +40,7 @@ // using namespace Slang; -namespace renderer_test { +namespace slang_graphics { class D3D11Renderer : public Renderer { diff --git a/tools/render-test/render-d3d11.h b/tools/slang-graphics/render-d3d11.h index 59142731d..7b3d25e9f 100644 --- a/tools/render-test/render-d3d11.h +++ b/tools/slang-graphics/render-d3d11.h @@ -1,10 +1,10 @@ // render-d3d11.h #pragma once -namespace renderer_test { +namespace slang_graphics { class Renderer; Renderer* createD3D11Renderer(); -} // renderer_test +} // slang_graphics diff --git a/tools/render-test/render-d3d12.cpp b/tools/slang-graphics/render-d3d12.cpp index 7603332b4..24c9ecacb 100644 --- a/tools/render-test/render-d3d12.cpp +++ b/tools/slang-graphics/render-d3d12.cpp @@ -3,14 +3,14 @@ #include "render-d3d12.h" -#include "options.h" +//WORKING:#include "options.h" #include "render.h" #include "surface.h" // In order to use the Slang API, we need to include its header -#include <slang.h> +//WORKING:#include <slang.h> // We will be rendering with Direct3D 12, so we need to include // the Windows and D3D12 headers @@ -46,7 +46,7 @@ #define ENABLE_DEBUG_LAYER 1 -namespace renderer_test { +namespace slang_graphics { using namespace Slang; class D3D12Renderer : public Renderer diff --git a/tools/render-test/render-d3d12.h b/tools/slang-graphics/render-d3d12.h index 259af7f7b..5f0eea4d2 100644 --- a/tools/render-test/render-d3d12.h +++ b/tools/slang-graphics/render-d3d12.h @@ -1,10 +1,10 @@ // render-d3d12.h #pragma once -namespace renderer_test { +namespace slang_graphics { class Renderer; Renderer* createD3D12Renderer(); -} // renderer_test +} // slang_graphics diff --git a/tools/render-test/render-gl.cpp b/tools/slang-graphics/render-gl.cpp index dc9f0c43a..f85a81ca4 100644 --- a/tools/render-test/render-gl.cpp +++ b/tools/slang-graphics/render-gl.cpp @@ -1,7 +1,7 @@ // render-gl.cpp #include "render-gl.h" -#include "options.h" +//WORKING:#include "options.h" #include "render.h" #include <assert.h> @@ -73,12 +73,12 @@ using namespace Slang; -namespace renderer_test { +namespace slang_graphics { class GLRenderer : public Renderer { public: - + // Renderer implementation virtual SlangResult initialize(const Desc& desc, void* inWindowHandle) override; virtual void setClearColor(const float color[4]) override; @@ -176,7 +176,7 @@ public: { glDeleteTextures(1, &m_handle); } - } + } Usage m_initialUsage; GLRenderer* m_renderer; @@ -228,7 +228,7 @@ public: m_renderer->glDeleteProgram(m_id); } } - + GLuint m_id; GLRenderer* m_renderer; }; @@ -253,7 +253,7 @@ public: void flushStateForDraw(); GLuint loadShader(GLenum stage, char const* source); void debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message); - + /// Returns GlPixelFormat::Unknown if not an equivalent static GlPixelFormat _getGlPixelFormat(Format format); @@ -265,7 +265,7 @@ public: HDC m_hdc; HGLRC m_glContext; float m_clearColor[4] = { 0, 0, 0, 0 }; - + RefPtr<ShaderProgramImpl> m_boundShaderProgram; RefPtr<InputLayoutImpl> m_boundInputLayout; @@ -282,7 +282,7 @@ public: MAP_GL_EXTENSION_FUNCS(DECLARE_GL_EXTENSION_FUNC) #undef DECLARE_GL_EXTENSION_FUNC - static const GlPixelFormatInfo s_pixelFormatInfos[]; /// Maps GlPixelFormat to a format info + static const GlPixelFormatInfo s_pixelFormatInfos[]; /// Maps GlPixelFormat to a format info }; /* static */GLRenderer::GlPixelFormat GLRenderer::_getGlPixelFormat(Format format) @@ -294,7 +294,7 @@ public: } } -/* static */ const GLRenderer::GlPixelFormatInfo GLRenderer::s_pixelFormatInfos[] = +/* static */ const GLRenderer::GlPixelFormatInfo GLRenderer::s_pixelFormatInfos[] = { // internalType, format, formatType { 0, 0, 0}, // GlPixelFormat::Unknown @@ -356,7 +356,7 @@ void GLRenderer::bindBufferImpl(int target, UInt startSlot, UInt slotCount, Buff BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(buffers[ii]); GLuint bufferID = buffer ? buffer->m_handle : 0; - + assert(!offsets || !offsets[ii]); glBindBufferBase(target, (GLuint)slot, bufferID); @@ -605,7 +605,7 @@ TextureResource* GLRenderer::createTextureResource(Resource::Usage initialUsage, const GLint internalFormat = info.internalFormat; const GLenum format = info.format; const GLenum formatType = info.formatType; - + RefPtr<TextureResourceImpl> texture(new TextureResourceImpl(initialUsage, srcDesc, this)); GLenum target = 0; @@ -665,7 +665,7 @@ TextureResource* GLRenderer::createTextureResource(Resource::Usage initialUsage, } glBindTexture(target, handle); - + int slice = 0; for (int i = 0; i < effectiveArraySize; i++) { @@ -681,7 +681,7 @@ TextureResource* GLRenderer::createTextureResource(Resource::Usage initialUsage, { target = GL_TEXTURE_CUBE_MAP; glBindTexture(target, handle); - + int slice = 0; for (int j = 0; j < 6; j++) { @@ -719,7 +719,7 @@ TextureResource* GLRenderer::createTextureResource(Resource::Usage initialUsage, glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT); - + // Assume regular sampling (might be superseded - if a combined sampler wanted) glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -750,7 +750,7 @@ static GLenum _calcTarget(Resource::Usage usage) } } -BufferResource* GLRenderer::createBufferResource(Resource::Usage initialUsage, const BufferResource::Desc& descIn, const void* initData) +BufferResource* GLRenderer::createBufferResource(Resource::Usage initialUsage, const BufferResource::Desc& descIn, const void* initData) { BufferResource::Desc desc(descIn); desc.setDefaults(initialUsage); @@ -758,7 +758,7 @@ BufferResource* GLRenderer::createBufferResource(Resource::Usage initialUsage, c const GLenum target = _calcTarget(initialUsage); // TODO: should derive from desc... const GLenum usage = _calcUsage(initialUsage); - + GLuint bufferID = 0; glGenBuffers(1, &bufferID); glBindBuffer(target, bufferID); @@ -842,7 +842,7 @@ void GLRenderer::setVertexBuffers(UInt startSlot, UInt slotCount, BufferResource BufferResourceImpl* buffer = static_cast<BufferResourceImpl*>(buffers[ii]); GLuint bufferID = buffer ? buffer->m_handle : 0; - + m_boundVertexStreamBuffers[slot] = bufferID; m_boundVertexStreamStrides[slot] = strides[ii]; m_boundVertexStreamOffsets[slot] = offsets[ii]; @@ -857,7 +857,7 @@ void GLRenderer::setShaderProgram(ShaderProgram* programIn) glUseProgram(programID); } -void GLRenderer::draw(UInt vertexCount, UInt startVertex = 0) +void GLRenderer::draw(UInt vertexCount, UInt startVertex = 0) { flushStateForDraw(); @@ -884,7 +884,7 @@ BindingState* GLRenderer::createBindingState(const BindingState::Desc& bindingSt auto& dstDetail = dstDetails[i]; const auto& srcBinding = srcBindings[i]; - + switch (srcBinding.bindingType) { case BindingType::Texture: diff --git a/tools/render-test/render-gl.h b/tools/slang-graphics/render-gl.h index 4e6de970c..2b211cda4 100644 --- a/tools/render-test/render-gl.h +++ b/tools/slang-graphics/render-gl.h @@ -1,10 +1,10 @@ // render-d3d11.h #pragma once -namespace renderer_test { +namespace slang_graphics { class Renderer; Renderer* createGLRenderer(); -} // renderer_test +} // slang_graphics diff --git a/tools/render-test/render-vk.cpp b/tools/slang-graphics/render-vk.cpp index bbdc2f08c..d7cd93e67 100644 --- a/tools/render-test/render-vk.cpp +++ b/tools/slang-graphics/render-vk.cpp @@ -1,7 +1,7 @@ // render-vk.cpp #include "render-vk.h" -#include "options.h" +//WORKING:#include "options.h" #include "render.h" #include "../../source/core/smart-pointer.h" @@ -26,14 +26,14 @@ # endif #endif -namespace renderer_test { +namespace slang_graphics { using namespace Slang; class VKRenderer : public Renderer { public: enum { kMaxRenderTargets = 8, kMaxAttachments = kMaxRenderTargets + 1 }; - + // Renderer implementation virtual SlangResult initialize(const Desc& desc, void* inWindowHandle) override; virtual void setClearColor(const float color[4]) override; @@ -66,12 +66,12 @@ public: class Buffer { public: - /// Initialize a buffer with specified size, and memory props + /// Initialize a buffer with specified size, and memory props Result init(const VulkanApi& api, size_t bufferSize, VkBufferUsageFlags usage, VkMemoryPropertyFlags reqMemoryProperties); /// Returns true if has been initialized bool isInitialized() const { return m_api != nullptr; } - + // Default Ctor Buffer(): m_api(nullptr) @@ -91,7 +91,7 @@ public: VkDeviceMemory m_memory; const VulkanApi* m_api; }; - + class InputLayoutImpl : public InputLayout { public: @@ -148,10 +148,10 @@ public: } Usage m_initialUsage; - - VkImage m_image = VK_NULL_HANDLE; + + VkImage m_image = VK_NULL_HANDLE; VkDeviceMemory m_imageMemory = VK_NULL_HANDLE; - + const VulkanApi* m_api; }; @@ -168,8 +168,8 @@ public: VkPipelineShaderStageCreateInfo m_compute; VkPipelineShaderStageCreateInfo m_vertex; VkPipelineShaderStageCreateInfo m_fragment; - - List<char> m_buffers[2]; //< To keep storage of code in scope + + List<char> m_buffers[2]; //< To keep storage of code in scope }; struct BindingDetail @@ -185,7 +185,7 @@ public: typedef BindingState Parent; BindingStateImpl(const Desc& desc, const VulkanApi* api): - Parent(desc), + Parent(desc), m_api(api) { } @@ -263,7 +263,7 @@ public: VkBool32 handleDebugMessage(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg); - + VkPipelineShaderStageCreateInfo compileEntryPoint( ShaderProgram::KernelDesc const& kernelDesc, VkShaderStageFlagBits stage, @@ -272,7 +272,7 @@ public: static VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageCallback(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t srcObject, size_t location, int32_t msgCode, const char* pLayerPrefix, const char* pMsg, void* pUserData); - /// Returns true if m_currentPipeline matches the current configuration + /// Returns true if m_currentPipeline matches the current configuration Pipeline* _getPipeline(); bool _isEqual(const Pipeline& pipeline) const; Slang::Result _createPipeline(RefPtr<Pipeline>& pipelineOut); @@ -293,7 +293,7 @@ public: Pipeline* m_currentPipeline = nullptr; List<BoundVertexBuffer> m_boundVertexBuffers; - + VkPrimitiveTopology m_primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; VkDevice m_device = VK_NULL_HANDLE; @@ -351,7 +351,7 @@ Result VKRenderer::Buffer::init(const VulkanApi& api, size_t bufferSize, VkBuffe bool VKRenderer::_isEqual(const Pipeline& pipeline) const { - return + return pipeline.m_bindingState == m_currentBindingState && pipeline.m_primitiveTopology == m_primitiveTopology && pipeline.m_inputLayout == m_currentInputLayout && @@ -364,7 +364,7 @@ VKRenderer::Pipeline* VKRenderer::_getPipeline() { return m_currentPipeline; } - + // Look for a match in the cache for (int i = 0; i < int(m_pipelineCache.Count()); ++i) { @@ -415,7 +415,7 @@ Slang::Result VKRenderer::_createPipeline(RefPtr<Pipeline>& pipelineOut) const auto& srcBinding = srcBindings[i]; VkDescriptorSetLayoutBinding dstBinding = {}; - + dstBinding.descriptorCount = 1; switch (srcBinding.bindingType) @@ -447,7 +447,7 @@ Slang::Result VKRenderer::_createPipeline(RefPtr<Pipeline>& pipelineOut) } case BindingType::Texture: { - dstBinding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; + dstBinding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; dstBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; dstBindings.Add(dstBinding); @@ -457,7 +457,7 @@ Slang::Result VKRenderer::_createPipeline(RefPtr<Pipeline>& pipelineOut) } case BindingType::Sampler: { - dstBinding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; + dstBinding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER; dstBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; dstBindings.Add(dstBinding); @@ -506,8 +506,8 @@ Slang::Result VKRenderer::_createPipeline(RefPtr<Pipeline>& pipelineOut) } } VkDescriptorPoolCreateInfo descriptorPoolInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; - - descriptorPoolInfo.maxSets = 128; // TODO: actually pick a size. + + descriptorPoolInfo.maxSets = 128; // TODO: actually pick a size. descriptorPoolInfo.poolSizeCount = uint32_t(poolSizes.Count()); descriptorPoolInfo.pPoolSizes = poolSizes.Buffer(); @@ -521,13 +521,13 @@ Slang::Result VKRenderer::_createPipeline(RefPtr<Pipeline>& pipelineOut) descriptorSetLayoutInfo.pBindings = dstBindings.Buffer(); SLANG_VK_CHECK(m_api.vkCreateDescriptorSetLayout(m_device, &descriptorSetLayoutInfo, nullptr, &pipeline->m_descriptorSetLayout)); - } - + } + // Create a descriptor set based on our layout { VkDescriptorSetAllocateInfo descriptorSetAllocInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO }; descriptorSetAllocInfo.descriptorPool = pipeline->m_descriptorPool; - descriptorSetAllocInfo.descriptorSetCount = 1; + descriptorSetAllocInfo.descriptorSetCount = 1; descriptorSetAllocInfo.pSetLayouts = &pipeline->m_descriptorSetLayout; SLANG_VK_CHECK(m_api.vkAllocateDescriptorSets(m_device, &descriptorSetAllocInfo, &pipeline->m_descriptorSet)); @@ -586,7 +586,7 @@ Slang::Result VKRenderer::_createPipeline(RefPtr<Pipeline>& pipelineOut) } writeInfo.pBufferInfo = &bufferInfos.Last(); - + writes.Add(writeInfo); break; } @@ -640,7 +640,7 @@ Slang::Result VKRenderer::_createPipeline(RefPtr<Pipeline>& pipelineOut) { m_api.vkUpdateDescriptorSets(m_device, uint32_t(writes.Count()), writes.Buffer(), 0, nullptr); } - + // Create a pipeline layout based on our descriptor set layout(s) VkPipelineLayoutCreateInfo pipelineLayoutInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; @@ -683,7 +683,7 @@ Slang::Result VKRenderer::_createPipeline(RefPtr<Pipeline>& pipelineOut) if (m_currentInputLayout) { vertexInputBindingDescription.binding = 0; - vertexInputBindingDescription.stride = m_currentInputLayout->m_vertexSize; + vertexInputBindingDescription.stride = m_currentInputLayout->m_vertexSize; vertexInputBindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; const auto& srcAttributeDescs = m_currentInputLayout->m_vertexDescs; @@ -713,7 +713,7 @@ Slang::Result VKRenderer::_createPipeline(RefPtr<Pipeline>& pipelineOut) VkRect2D scissor = {}; scissor.offset = { 0, 0 }; scissor.extent = { uint32_t(width), uint32_t(height) }; - + VkPipelineViewportStateCreateInfo viewportState = {}; viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; viewportState.viewportCount = 1; @@ -752,7 +752,7 @@ Slang::Result VKRenderer::_createPipeline(RefPtr<Pipeline>& pipelineOut) colorBlending.blendConstants[3] = 0.0f; VkGraphicsPipelineCreateInfo pipelineInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; - + pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; pipelineInfo.stageCount = 2; pipelineInfo.pStages = shaderStages; @@ -834,11 +834,11 @@ Result VKRenderer::_beginPass() VkViewport& dstViewport = viewports[i]; dstViewport.x = 0.0f; - dstViewport.y = 0.0f; - dstViewport.width = float(width); - dstViewport.height = float(height); - dstViewport.minDepth = 0.0f; - dstViewport.maxDepth = 1.0f; + dstViewport.y = 0.0f; + dstViewport.width = float(width); + dstViewport.height = float(height); + dstViewport.minDepth = 0.0f; + dstViewport.maxDepth = 1.0f; } m_api.vkCmdSetScissor(cmdBuffer, 0, numRenderTargets, rects); @@ -937,7 +937,7 @@ VkPipelineShaderStageCreateInfo VKRenderer::compileEntryPoint( bufferOut.InsertRange(0, dataBegin, codeSize); char* codeBegin = bufferOut.Buffer(); - + VkShaderModuleCreateInfo moduleCreateInfo = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; moduleCreateInfo.pCode = (uint32_t*)codeBegin; moduleCreateInfo.codeSize = codeSize; @@ -950,7 +950,7 @@ VkPipelineShaderStageCreateInfo VKRenderer::compileEntryPoint( shaderStageCreateInfo.module = module; shaderStageCreateInfo.pName = "main"; - + return shaderStageCreateInfo; } @@ -968,7 +968,7 @@ SlangResult VKRenderer::initialize(const Desc& desc, void* inWindowHandle) applicationInfo.pEngineName = "slang-render-test"; applicationInfo.apiVersion = VK_API_VERSION_1_0; - char const* instanceExtensions[] = + char const* instanceExtensions[] = { VK_KHR_SURFACE_EXTENSION_NAME, @@ -993,7 +993,7 @@ SlangResult VKRenderer::initialize(const Desc& desc, void* inWindowHandle) #if ENABLE_VALIDATION_LAYER const char* layerNames[] = { "VK_LAYER_LUNARG_standard_validation" }; - instanceCreateInfo.enabledLayerCount = SLANG_COUNT_OF(layerNames); + instanceCreateInfo.enabledLayerCount = SLANG_COUNT_OF(layerNames); instanceCreateInfo.ppEnabledLayerNames = layerNames; #endif @@ -1020,9 +1020,9 @@ SlangResult VKRenderer::initialize(const Desc& desc, void* inWindowHandle) // TODO: allow override of selected device uint32_t selectedDeviceIndex = 0; - + SLANG_RETURN_ON_FAIL(m_api.initPhysicalDevice(physicalDevices[selectedDeviceIndex])); - + int queueFamilyIndex = m_api.findQueue(VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT); assert(queueFamilyIndex >= 0); @@ -1070,7 +1070,7 @@ SlangResult VKRenderer::initialize(const Desc& desc, void* inWindowHandle) platformDesc = &winPlatformDesc; #endif - SLANG_RETURN_ON_FAIL(m_swapChain.init(&m_deviceQueue, desc, platformDesc)); + SLANG_RETURN_ON_FAIL(m_swapChain.init(&m_deviceQueue, desc, platformDesc)); } // depth/stencil? @@ -1181,7 +1181,7 @@ void VKRenderer::clearFrame() } void VKRenderer::presentFrame() -{ +{ _endRender(); const bool vsync = true; @@ -1244,7 +1244,7 @@ static VkBufferUsageFlags _calcBufferUsageFlags(int bindFlags, int cpuAccessFlag usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; } - return usage; + return usage; } static VkImageUsageFlagBits _calcImageUsageFlags(Resource::BindFlag::Enum bind) @@ -1284,7 +1284,7 @@ static VkImageUsageFlagBits _calcImageUsageFlags(int bindFlags) static VkImageUsageFlags _calcImageUsageFlags(int bindFlags, int cpuAccessFlags, const void* initData) { VkImageUsageFlags usage = _calcImageUsageFlags(bindFlags); - + usage |= VK_IMAGE_USAGE_SAMPLED_BIT; if (cpuAccessFlags & Resource::AccessFlag::Read) @@ -1300,7 +1300,7 @@ static VkImageUsageFlags _calcImageUsageFlags(int bindFlags, int cpuAccessFlags, return usage; } -void VKRenderer::_transitionImageLayout(VkImage image, VkFormat format, const TextureResource::Desc& desc, VkImageLayout oldLayout, VkImageLayout newLayout) +void VKRenderer::_transitionImageLayout(VkImage image, VkFormat format, const TextureResource::Desc& desc, VkImageLayout oldLayout, VkImageLayout newLayout) { VkImageMemoryBarrier barrier = {}; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; @@ -1318,7 +1318,7 @@ void VKRenderer::_transitionImageLayout(VkImage image, VkFormat format, const Te VkPipelineStageFlags sourceStage; VkPipelineStageFlags destinationStage; - if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) + if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { barrier.srcAccessMask = 0; barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; @@ -1326,7 +1326,7 @@ void VKRenderer::_transitionImageLayout(VkImage image, VkFormat format, const Te sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT; } - else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) + else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; @@ -1334,7 +1334,7 @@ void VKRenderer::_transitionImageLayout(VkImage image, VkFormat format, const Te sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT; destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; } - else + else { assert(!"unsupported layout transition!"); return; @@ -1403,10 +1403,10 @@ TextureResource* VKRenderer::createTextureResource(Resource::Usage initialUsage, imageInfo.mipLevels = desc.numMipLevels; imageInfo.arrayLayers = arraySize; - + imageInfo.format = format; - imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; + imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; imageInfo.usage = _calcImageUsageFlags(desc.bindFlags, desc.cpuAccessFlags, initData); imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; @@ -1415,7 +1415,7 @@ TextureResource* VKRenderer::createTextureResource(Resource::Usage initialUsage, SLANG_VK_RETURN_NULL_ON_FAIL(m_api.vkCreateImage(m_device, &imageInfo, nullptr, &texture->m_image)); } - + VkMemoryRequirements memRequirements; m_api.vkGetImageMemoryRequirements(m_device, texture->m_image, &memRequirements); @@ -1424,18 +1424,18 @@ TextureResource* VKRenderer::createTextureResource(Resource::Usage initialUsage, VkMemoryPropertyFlags reqMemoryProperties = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; VkMemoryAllocateInfo allocInfo = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO}; - + int memoryTypeIndex = m_api.findMemoryTypeIndex(memRequirements.memoryTypeBits, reqMemoryProperties); assert(memoryTypeIndex >= 0); - + VkMemoryPropertyFlags actualMemoryProperites = m_api.m_deviceMemoryProperties.memoryTypes[memoryTypeIndex].propertyFlags; - + allocInfo.allocationSize = memRequirements.size; allocInfo.memoryTypeIndex = memoryTypeIndex; SLANG_VK_RETURN_NULL_ON_FAIL(m_api.vkAllocateMemory(m_device, &allocInfo, nullptr, &texture->m_imageMemory)); } - + // Bind the memory to the image m_api.vkBindImageMemory(m_device, texture->m_image, texture->m_imageMemory, 0); @@ -1463,8 +1463,8 @@ TextureResource* VKRenderer::createTextureResource(Resource::Usage initialUsage, bufferSize += (rowSizeInBytes * numRows) * mipSize.depth; } - - // Calculate the total size taking into account the array + + // Calculate the total size taking into account the array bufferSize *= arraySize; Buffer uploadBuffer; @@ -1478,7 +1478,7 @@ TextureResource* VKRenderer::createTextureResource(Resource::Usage initialUsage, uint8_t* dstData; m_api.vkMapMemory(m_device, uploadBuffer.m_memory, 0, bufferSize, 0, (void**)&dstData); - + for (int i = 0; i < arraySize; ++i) { for (int j = 0; j < int(mipSizes.Count()); ++j) @@ -1491,12 +1491,12 @@ TextureResource* VKRenderer::createTextureResource(Resource::Usage initialUsage, for (int k = 0; k < mipSize.depth; k++) { - const uint8_t* srcData = (const uint8_t*)(initData->subResources[subResourceIndex]); + const uint8_t* srcData = (const uint8_t*)(initData->subResources[subResourceIndex]); for (int l = 0; l < numRows; l++) { ::memcpy(dstData, srcData, dstRowSizeInBytes); - + dstData += dstRowSizeInBytes; srcData += srcRowStride; } @@ -1510,7 +1510,7 @@ TextureResource* VKRenderer::createTextureResource(Resource::Usage initialUsage, } _transitionImageLayout(texture->m_image, format, texture->getDesc(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - + { size_t srcOffset = 0; for (int i = 0; i < arraySize; ++i) @@ -1518,21 +1518,21 @@ TextureResource* VKRenderer::createTextureResource(Resource::Usage initialUsage, for (int j = 0; j < int(mipSizes.Count()); ++j) { const auto& mipSize = mipSizes[j]; - + const int rowSizeInBytes = Surface::calcRowSize(desc.format, mipSize.width); const int numRows = Surface::calcNumRows(desc.format, mipSize.height); // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkBufferImageCopy.html // bufferRowLength and bufferImageHeight specify the data in buffer memory as a subregion of a larger two- or three-dimensional image, - // and control the addressing calculations of data in buffer memory. If either of these values is zero, that aspect of the buffer memory + // and control the addressing calculations of data in buffer memory. If either of these values is zero, that aspect of the buffer memory // is considered to be tightly packed according to the imageExtent. VkBufferImageCopy region = {}; region.bufferOffset = srcOffset; region.bufferRowLength = 0; //rowSizeInBytes; - region.bufferImageHeight = 0; - + region.bufferImageHeight = 0; + region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; region.imageSubresource.mipLevel = j; region.imageSubresource.baseArrayLayer = i; @@ -1567,7 +1567,7 @@ BufferResource* VKRenderer::createBufferResource(Resource::Usage initialUsage, c VkMemoryPropertyFlags reqMemoryProperties = 0; VkBufferUsageFlags usage = _calcBufferUsageFlags(desc.bindFlags, desc.cpuAccessFlags, initData); - + switch (initialUsage) { case Resource::Usage::ConstantBuffer: @@ -1599,7 +1599,7 @@ BufferResource* VKRenderer::createBufferResource(Resource::Usage initialUsage, c // Copy from staging buffer to real buffer VkCommandBuffer commandBuffer = m_deviceQueue.getCommandBuffer(); - + VkBufferCopy copyInfo = {}; copyInfo.size = bufferSize; m_api.vkCmdCopyBuffer(commandBuffer, buffer->m_uploadBuffer.m_buffer, buffer->m_buffer.m_buffer, 1, ©Info); @@ -1610,7 +1610,7 @@ BufferResource* VKRenderer::createBufferResource(Resource::Usage initialUsage, c return buffer.detach(); } -InputLayout* VKRenderer::createInputLayout(const InputElementDesc* elements, UInt numElements) +InputLayout* VKRenderer::createInputLayout(const InputElementDesc* elements, UInt numElements) { RefPtr<InputLayoutImpl> layout(new InputLayoutImpl); @@ -1632,8 +1632,8 @@ InputLayout* VKRenderer::createInputLayout(const InputElementDesc* elements, UIn return nullptr; } - dstDesc.offset = uint32_t(srcDesc.offset); - + dstDesc.offset = uint32_t(srcDesc.offset); + const size_t elementSize = RendererUtil::getFormatSize(srcDesc.format); assert(elementSize > 0); const size_t endElement = srcDesc.offset + elementSize; @@ -1857,7 +1857,7 @@ static VkImageViewType _calcImageViewType(TextureResource::Type type, const Text BindingState* VKRenderer::createBindingState(const BindingState::Desc& bindingStateDesc) -{ +{ RefPtr<BindingStateImpl> bindingState(new BindingStateImpl(bindingStateDesc, &m_api)); const auto& srcBindings = bindingStateDesc.m_bindings; @@ -1895,7 +1895,7 @@ BindingState* VKRenderer::createBindingState(const BindingState::Desc& bindingSt // Not sure how to handle typeless? if (bufferResourceDesc.elementSize == 0) { - info.format = VK_FORMAT_R32_SFLOAT; // DXGI_FORMAT_R32_TYPELESS ? + info.format = VK_FORMAT_R32_SFLOAT; // DXGI_FORMAT_R32_TYPELESS ? } info.buffer = bufferResource->m_buffer.m_buffer; @@ -1905,7 +1905,7 @@ BindingState* VKRenderer::createBindingState(const BindingState::Desc& bindingSt SLANG_VK_RETURN_NULL_ON_FAIL(m_api.vkCreateBufferView(m_device, &info, nullptr, &dstDetail.m_uav)); } - // TODO: Setup views. + // TODO: Setup views. // VkImageView srv @@ -1914,10 +1914,10 @@ BindingState* VKRenderer::createBindingState(const BindingState::Desc& bindingSt case BindingType::Sampler: { VkSamplerCreateInfo samplerInfo = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO }; - + samplerInfo.magFilter = VK_FILTER_LINEAR; samplerInfo.minFilter = VK_FILTER_LINEAR; - + samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT; samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT; samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; @@ -1960,7 +1960,7 @@ BindingState* VKRenderer::createBindingState(const BindingState::Desc& bindingSt } // Create the image view - + VkImageViewCreateInfo viewInfo = {}; viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; viewInfo.image = textureResource->m_image; @@ -1978,7 +1978,7 @@ BindingState* VKRenderer::createBindingState(const BindingState::Desc& bindingSt viewInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; SLANG_VK_RETURN_NULL_ON_FAIL(m_api.vkCreateImageView(m_device, &viewInfo, nullptr, &dstDetail.m_srv)); - + break; } case BindingType::CombinedTextureSampler: diff --git a/tools/render-test/render-vk.h b/tools/slang-graphics/render-vk.h index 7f6d789d0..720f35a2c 100644 --- a/tools/render-test/render-vk.h +++ b/tools/slang-graphics/render-vk.h @@ -1,10 +1,10 @@ // render-vk.h #pragma once -namespace renderer_test { +namespace slang_graphics { class Renderer; Renderer* createVKRenderer(); -} // renderer_test +} // slang_graphics diff --git a/tools/render-test/render.cpp b/tools/slang-graphics/render.cpp index bfb7aeb94..3595f73c1 100644 --- a/tools/render-test/render.cpp +++ b/tools/slang-graphics/render.cpp @@ -3,7 +3,7 @@ #include "../../source/core/slang-math.h" -namespace renderer_test { +namespace slang_graphics { using namespace Slang; /* static */const Resource::BindFlag::Enum Resource::s_requiredBinding[] = diff --git a/tools/render-test/render.h b/tools/slang-graphics/render.h index 6a3c58a05..92e9c0930 100644 --- a/tools/render-test/render.h +++ b/tools/slang-graphics/render.h @@ -10,7 +10,7 @@ #include "../../source/core/smart-pointer.h" #include "../../source/core/list.h" -namespace renderer_test { +namespace slang_graphics { // Had to move here, because Options needs types defined here typedef intptr_t Int; diff --git a/tools/render-test/resource-d3d12.cpp b/tools/slang-graphics/resource-d3d12.cpp index 160c7f898..bb39d2529 100644 --- a/tools/render-test/resource-d3d12.cpp +++ b/tools/slang-graphics/resource-d3d12.cpp @@ -1,7 +1,7 @@ // resource-d3d12.cpp #include "resource-d3d12.h" -namespace renderer_test { +namespace slang_graphics { using namespace Slang; /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! D3D12BarrierSubmitter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ @@ -97,7 +97,7 @@ Result D3D12CounterFence::init(ID3D12Device* device, uint64_t initialValue) UInt64 D3D12CounterFence::nextSignal(ID3D12CommandQueue* commandQueue) { - // Increment the fence value. Save on the frame - we'll know that frame is done when the fence value >= + // Increment the fence value. Save on the frame - we'll know that frame is done when the fence value >= m_currentValue++; // Schedule a Signal command in the queue. Result res = commandQueue->Signal(m_fence, m_currentValue); diff --git a/tools/render-test/resource-d3d12.h b/tools/slang-graphics/resource-d3d12.h index 1f0ba638b..6040291cc 100644 --- a/tools/render-test/resource-d3d12.h +++ b/tools/slang-graphics/resource-d3d12.h @@ -13,11 +13,11 @@ #include "../../slang-com-ptr.h" #include "d3d-util.h" -namespace renderer_test { +namespace slang_graphics { // Enables more conservative barriers - restoring the state of resources after they are used. // Should not need to be enabled in normal builds, as the barriers should correctly sync resources -// If enabling fixes an issue it implies regular barriers are not correctly used. +// If enabling fixes an issue it implies regular barriers are not correctly used. #define SLANG_ENABLE_CONSERVATIVE_RESOURCE_BARRIERS 0 struct D3D12BarrierSubmitter @@ -26,7 +26,7 @@ struct D3D12BarrierSubmitter /// Expand one space to hold a barrier SLANG_FORCE_INLINE D3D12_RESOURCE_BARRIER& expandOne() { return (m_numBarriers < MAX_BARRIERS) ? m_barriers[m_numBarriers++] : _expandOne(); } - /// Flush barriers to command list + /// Flush barriers to command list SLANG_FORCE_INLINE void flush() { if (m_numBarriers > 0) _flush(); } /// Transition resource from prevState to nextState @@ -79,7 +79,7 @@ public: /// Get the completed value SLANG_FORCE_INLINE uint64_t getCompletedValue() const { return m_fence->GetCompletedValue(); } - /// Waits for the the specified value + /// Waits for the the specified value void waitUntilCompleted(uint64_t completedValue); /// Ctor diff --git a/tools/slang-graphics/slang-graphics.vcxproj b/tools/slang-graphics/slang-graphics.vcxproj new file mode 100644 index 000000000..ce7502326 --- /dev/null +++ b/tools/slang-graphics/slang-graphics.vcxproj @@ -0,0 +1,212 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{222F7498-B40C-4F3F-A704-DDEB91A4484A}</ProjectGuid> + <IgnoreWarnCompileDuplicatedFilename>true</IgnoreWarnCompileDuplicatedFilename> + <Keyword>Win32Proj</Keyword> + <RootNamespace>slang-graphics</RootNamespace> + <WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>..\..\bin\windows-x86\debug\</OutDir> + <IntDir>..\..\intermediate\windows-x86\debug\slang-graphics\</IntDir> + <TargetName>slang-graphics</TargetName> + <TargetExt>.lib</TargetExt> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>..\..\bin\windows-x64\debug\</OutDir> + <IntDir>..\..\intermediate\windows-x64\debug\slang-graphics\</IntDir> + <TargetName>slang-graphics</TargetName> + <TargetExt>.lib</TargetExt> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>..\..\bin\windows-x86\release\</OutDir> + <IntDir>..\..\intermediate\windows-x86\release\slang-graphics\</IntDir> + <TargetName>slang-graphics</TargetName> + <TargetExt>.lib</TargetExt> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>..\..\bin\windows-x64\release\</OutDir> + <IntDir>..\..\intermediate\windows-x64\release\slang-graphics\</IntDir> + <TargetName>slang-graphics</TargetName> + <TargetExt>.lib</TargetExt> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..;..\..\external;..\..\source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <Optimization>Disabled</Optimization> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>"$(SolutionDir)tools\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/x86/" "../../bin/windows-x86/debug/"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..;..\..\external;..\..\source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <DebugInformationFormat>EditAndContinue</DebugInformationFormat> + <Optimization>Disabled</Optimization> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + <PostBuildEvent> + <Command>"$(SolutionDir)tools\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/x64/" "../../bin/windows-x64/debug/"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..;..\..\external;..\..\source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <Optimization>Full</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <MinimalRebuild>false</MinimalRebuild> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>"$(SolutionDir)tools\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/x86/" "../../bin/windows-x86/release/"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..;..\..\external;..\..\source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <Optimization>Full</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <MinimalRebuild>false</MinimalRebuild> + <StringPooling>true</StringPooling> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + <PostBuildEvent> + <Command>"$(SolutionDir)tools\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/x64/" "../../bin/windows-x64/release/"</Command> + </PostBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="circular-resource-heap-d3d12.h" /> + <ClInclude Include="d3d-util.h" /> + <ClInclude Include="descriptor-heap-d3d12.h" /> + <ClInclude Include="render-d3d11.h" /> + <ClInclude Include="render-d3d12.h" /> + <ClInclude Include="render-gl.h" /> + <ClInclude Include="render-vk.h" /> + <ClInclude Include="render.h" /> + <ClInclude Include="resource-d3d12.h" /> + <ClInclude Include="surface.h" /> + <ClInclude Include="vk-api.h" /> + <ClInclude Include="vk-device-queue.h" /> + <ClInclude Include="vk-module.h" /> + <ClInclude Include="vk-swap-chain.h" /> + <ClInclude Include="vk-util.h" /> + <ClInclude Include="window.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="circular-resource-heap-d3d12.cpp" /> + <ClCompile Include="d3d-util.cpp" /> + <ClCompile Include="descriptor-heap-d3d12.cpp" /> + <ClCompile Include="render-d3d11.cpp" /> + <ClCompile Include="render-d3d12.cpp" /> + <ClCompile Include="render-gl.cpp" /> + <ClCompile Include="render-vk.cpp" /> + <ClCompile Include="render.cpp" /> + <ClCompile Include="resource-d3d12.cpp" /> + <ClCompile Include="surface.cpp" /> + <ClCompile Include="vk-api.cpp" /> + <ClCompile Include="vk-device-queue.cpp" /> + <ClCompile Include="vk-module.cpp" /> + <ClCompile Include="vk-swap-chain.cpp" /> + <ClCompile Include="vk-util.cpp" /> + <ClCompile Include="window.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tools/slang-graphics/slang-graphics.vcxproj.filters b/tools/slang-graphics/slang-graphics.vcxproj.filters new file mode 100644 index 000000000..b1e4c42a3 --- /dev/null +++ b/tools/slang-graphics/slang-graphics.vcxproj.filters @@ -0,0 +1,111 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{21EB8090-0D4E-1035-B6D3-48EBA215DCB7}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{E9C7FDCE-D52A-8D73-7EB0-C5296AF258F6}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="circular-resource-heap-d3d12.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="d3d-util.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="descriptor-heap-d3d12.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="render-d3d11.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="render-d3d12.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="render-gl.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="render-vk.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="render.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="resource-d3d12.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="surface.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="vk-api.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="vk-device-queue.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="vk-module.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="vk-swap-chain.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="vk-util.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="window.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="circular-resource-heap-d3d12.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="d3d-util.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="descriptor-heap-d3d12.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="render-d3d11.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="render-d3d12.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="render-gl.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="render-vk.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="render.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="resource-d3d12.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="surface.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="vk-api.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="vk-device-queue.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="vk-module.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="vk-swap-chain.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="vk-util.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="window.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/tools/render-test/surface.cpp b/tools/slang-graphics/surface.cpp index eabe555c3..9d91f8778 100644 --- a/tools/render-test/surface.cpp +++ b/tools/slang-graphics/surface.cpp @@ -6,7 +6,7 @@ #include "../../source/core/list.h" -namespace renderer_test { +namespace slang_graphics { using namespace Slang; class MallocSurfaceAllocator: public SurfaceAllocator @@ -80,10 +80,10 @@ void MallocSurfaceAllocator::deallocate(Surface& surface) return int(pixelSize * width); } -/* static */int Surface::calcNumRows(Format format, int height) -{ +/* static */int Surface::calcNumRows(Format format, int height) +{ // Don't have any compressed types, so number of rows is same as the height - return height; + return height; } void Surface::init() @@ -94,7 +94,7 @@ void Surface::init() m_data = nullptr; m_numRows = 0; m_rowStrideInBytes = 0; - // NOTE! does not clear the allocator. + // NOTE! does not clear the allocator. // If called with an allocation memory will leak! } @@ -141,7 +141,7 @@ void Surface::setUnowned(int width, int height, Format format, int strideInBytes m_data = (uint8_t*)data; m_numRows = Surface::calcNumRows(format, height); - + const int rowSizeInBytes = Surface::calcRowSize(format, width); assert((strideInBytes > 0 && rowSizeInBytes <= strideInBytes) || (strideInBytes < 0 && rowSizeInBytes <= -strideInBytes)); } @@ -209,8 +209,8 @@ SlangResult Surface::set(int width, int height, Format format, int srcRowStride, for (int i = 0; i < m_numRows; i++) { - ::memcpy(dstRow, srcRow, rowSize); - + ::memcpy(dstRow, srcRow, rowSize); + srcRow += srcRowStride; dstRow += m_rowStrideInBytes; } diff --git a/tools/render-test/surface.h b/tools/slang-graphics/surface.h index c7460238f..026ba25ed 100644 --- a/tools/render-test/surface.h +++ b/tools/slang-graphics/surface.h @@ -2,8 +2,8 @@ #pragma once #include "render.h" - -namespace renderer_test { + +namespace slang_graphics { class Surface; @@ -21,7 +21,7 @@ class Surface { public: - enum + enum { kDefaultAlignment = sizeof(void*) }; @@ -35,11 +35,11 @@ class Surface void init(); /// Set unowned - void setUnowned(int width, int height, Format format, int strideInBytes, void* data); + void setUnowned(int width, int height, Format format, int strideInBytes, void* data); /// Set the contents - the memory will be owned by this surface (ie will be freed by the allocator when goes out of scope or is deallocated) Slang::Result set(int width, int height, Format format, int strideInBytes, const void* data, SurfaceAllocator* allocator); - + template <typename T> T* calcNextRow(T* ptr) const { return (T*)calcNextRow((void*)ptr); } template <typename T> @@ -53,7 +53,7 @@ class Surface /// Flips the contents vertically in place void flipInplaceVertically(); - + /// True if has some contents bool hasContents() const { return m_data != nullptr; } @@ -65,7 +65,7 @@ class Surface } /// Dtor ~Surface(); - + /// Get the size of the row in bytes static int calcRowSize(Format format, int width); /// Calculates the number of rows @@ -73,8 +73,8 @@ class Surface int m_width; int m_height; - Format m_format; - + Format m_format; + uint8_t* m_data; /// The data that makes up the image. If nullptr, has no data. Pointer to first 'row' of the image. int m_numRows; ///< Total amount of rows (typically same as height, but in compressed formats may be less) diff --git a/tools/render-test/vk-api.cpp b/tools/slang-graphics/vk-api.cpp index df222d8ad..0ffbf46eb 100644 --- a/tools/render-test/vk-api.cpp +++ b/tools/slang-graphics/vk-api.cpp @@ -3,13 +3,13 @@ #include "../../source/core/list.h" -namespace renderer_test { +namespace slang_graphics { using namespace Slang; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! VulkanApi !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -#define VK_API_CHECK_FUNCTION(x) && (x != nullptr) -#define VK_API_CHECK_FUNCTIONS(FUNCTION_LIST) true FUNCTION_LIST(VK_API_CHECK_FUNCTION) +#define VK_API_CHECK_FUNCTION(x) && (x != nullptr) +#define VK_API_CHECK_FUNCTIONS(FUNCTION_LIST) true FUNCTION_LIST(VK_API_CHECK_FUNCTION) bool VulkanApi::areDefined(ProcType type) const { @@ -92,10 +92,10 @@ int VulkanApi::findMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags prop assert(typeBits); const int numMemoryTypes = int(m_deviceMemoryProperties.memoryTypeCount); - - // bit holds current test bit against typeBits. Ie bit == 1 << typeBits - - uint32_t bit = 1; + + // bit holds current test bit against typeBits. Ie bit == 1 << typeBits + + uint32_t bit = 1; for (int i = 0; i < numMemoryTypes; ++i, bit += bit) { auto const& memoryType = m_deviceMemoryProperties.memoryTypes[i]; @@ -104,7 +104,7 @@ int VulkanApi::findMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags prop return i; } } - + //assert(!"failed to find a usable memory type"); return -1; } diff --git a/tools/render-test/vk-api.h b/tools/slang-graphics/vk-api.h index 521d6301d..0cbd3faf7 100644 --- a/tools/render-test/vk-api.h +++ b/tools/slang-graphics/vk-api.h @@ -3,7 +3,7 @@ #include "vk-module.h" -namespace renderer_test { +namespace slang_graphics { #define VK_API_GLOBAL_PROCS(x) \ x(vkGetInstanceProcAddr) \ @@ -154,17 +154,17 @@ struct VulkanApi { VK_API_ALL_PROCS(VK_API_DECLARE_PROC) - enum class ProcType + enum class ProcType { Global, - Instance, + Instance, Device, }; - /// Returns true if all the functions in the class are defined + /// Returns true if all the functions in the class are defined bool areDefined(ProcType type) const; - /// Sets up global parameters + /// Sets up global parameters Slang::Result initGlobalProcs(const VulkanModule& module); /// Initialize the instance functions Slang::Result initInstanceProcs(VkInstance instance); diff --git a/tools/render-test/vk-device-queue.cpp b/tools/slang-graphics/vk-device-queue.cpp index d40442c22..9e978117f 100644 --- a/tools/render-test/vk-device-queue.cpp +++ b/tools/slang-graphics/vk-device-queue.cpp @@ -5,7 +5,7 @@ #include <stdio.h> #include <assert.h> -namespace renderer_test { +namespace slang_graphics { using namespace Slang; VulkanDeviceQueue::~VulkanDeviceQueue() @@ -33,12 +33,12 @@ SlangResult VulkanDeviceQueue::init(const VulkanApi& api, VkQueue queue, int que m_semaphores[i] = VK_NULL_HANDLE; m_currentSemaphores[i] = VK_NULL_HANDLE; } - + m_numCommandBuffers = kMaxCommandBuffers; m_queueIndex = queueIndex; m_queue = queue; - + VkCommandPoolCreateInfo poolCreateInfo = {}; poolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; poolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; @@ -75,7 +75,7 @@ SlangResult VulkanDeviceQueue::init(const VulkanApi& api, VkQueue queue, int que { api.vkCreateSemaphore(api.m_device, &semaphoreCreateInfo, nullptr, &m_semaphores[i]); } - + // Second step of flush to prime command buffer flushStepB(); @@ -101,7 +101,7 @@ void VulkanDeviceQueue::flushStepA() submitInfo.pWaitDstStageMask = &stageFlags; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &m_commandBuffer; - + // Signal semaphores if (isCurrent(EventType::EndFrame)) { @@ -116,7 +116,7 @@ void VulkanDeviceQueue::flushStepA() // mark signaled fence value fence.value = m_nextFenceValue; fence.active = true; - + // increment fence value m_nextFenceValue++; @@ -147,10 +147,10 @@ void VulkanDeviceQueue::_updateFenceAtIndex( int fenceIndex, bool blocking) } void VulkanDeviceQueue::flushStepB() -{ +{ m_commandBufferIndex = (m_commandBufferIndex + 1) % m_numCommandBuffers; m_commandBuffer = m_commandBuffers[m_commandBufferIndex]; - + // non-blocking update of fence values for (int i = 0; i < m_numCommandBuffers; ++i) { @@ -159,7 +159,7 @@ void VulkanDeviceQueue::flushStepB() // blocking update of fence values _updateFenceAtIndex(m_commandBufferIndex, true); - + m_api->vkResetCommandBuffer(m_commandBuffer, 0); //m_api.vkResetCommandPool(m_api->m_device, m_commandPool, 0); @@ -185,7 +185,7 @@ void VulkanDeviceQueue::flushAndWait() VkSemaphore VulkanDeviceQueue::makeCurrent(EventType eventType) { - assert(!isCurrent(eventType)); + assert(!isCurrent(eventType)); VkSemaphore semaphore = m_semaphores[int(eventType)]; m_currentSemaphores[int(eventType)] = semaphore; return semaphore; diff --git a/tools/render-test/vk-device-queue.h b/tools/slang-graphics/vk-device-queue.h index 8381f5166..01ed16f5d 100644 --- a/tools/render-test/vk-device-queue.h +++ b/tools/slang-graphics/vk-device-queue.h @@ -3,11 +3,11 @@ #include "vk-api.h" -namespace renderer_test { +namespace slang_graphics { struct VulkanDeviceQueue { - enum + enum { kMaxCommandBuffers = 8, }; @@ -24,7 +24,7 @@ struct VulkanDeviceQueue /// Flushes the current command list, and steps to next (internally this is equivalent to a stepA followed by stepB) void flush(); - /// Performs a full flush, and then waits for idle. + /// Performs a full flush, and then waits for idle. void flushAndWait(); /// Blocks until all work submitted to GPU has completed @@ -49,7 +49,7 @@ struct VulkanDeviceQueue /// Get the API const VulkanApi* getApi() const { return m_api; } - /// Flushes the current command list + /// Flushes the current command list void flushStepA(); /// Steps to next command buffer and opens. May block if command buffer is still in use void flushStepB(); @@ -58,7 +58,7 @@ struct VulkanDeviceQueue ~VulkanDeviceQueue(); protected: - + struct Fence { VkFence fence; @@ -77,7 +77,7 @@ struct VulkanDeviceQueue VkCommandBuffer m_commandBuffers[kMaxCommandBuffers] = { VK_NULL_HANDLE }; Fence m_fences[kMaxCommandBuffers] = { {VK_NULL_HANDLE, 0, 0u} }; - + VkCommandBuffer m_commandBuffer = VK_NULL_HANDLE; VkSemaphore m_semaphores[int(EventType::CountOf)]; diff --git a/tools/render-test/vk-module.cpp b/tools/slang-graphics/vk-module.cpp index e98bd08cd..460e6550c 100644 --- a/tools/render-test/vk-module.cpp +++ b/tools/slang-graphics/vk-module.cpp @@ -5,13 +5,13 @@ #include <stdio.h> #include <assert.h> -#if SLANG_WINDOWS_FAMILY +#if SLANG_WINDOWS_FAMILY # include <windows.h> #else # include <dlfcn.h> #endif -namespace renderer_test { +namespace slang_graphics { using namespace Slang; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! VulkanModule !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @@ -28,8 +28,8 @@ Slang::Result VulkanModule::init() #if SLANG_WINDOWS_FAMILY dynamicLibraryName = "vulkan-1.dll"; - HMODULE module = ::LoadLibraryA(dynamicLibraryName); - m_module = (void*)module; + HMODULE module = ::LoadLibraryA(dynamicLibraryName); + m_module = (void*)module; #else dynamicLibraryName = "libvulkan.so.1"; m_module = dlopen(dynamicLibraryName, RTLD_NOW); @@ -53,7 +53,7 @@ PFN_vkVoidFunction VulkanModule::getFunction(const char* name) const } #if SLANG_WINDOWS_FAMILY return (PFN_vkVoidFunction)::GetProcAddress((HMODULE)m_module, name); -#else +#else return (PFN_vkVoidFunction)dlsym(m_module, name); #endif } @@ -65,8 +65,8 @@ void VulkanModule::destroy() return; } -#if SLANG_WINDOWS_FAMILY - ::FreeLibrary((HMODULE)m_module); +#if SLANG_WINDOWS_FAMILY + ::FreeLibrary((HMODULE)m_module); #else dlclose(m_module); #endif diff --git a/tools/render-test/vk-module.h b/tools/slang-graphics/vk-module.h index 0aed2303f..c72334db5 100644 --- a/tools/render-test/vk-module.h +++ b/tools/slang-graphics/vk-module.h @@ -14,7 +14,7 @@ #define VK_NO_PROTOTYPES #include <vulkan/vulkan.h> -namespace renderer_test { +namespace slang_graphics { struct VulkanModule { @@ -27,7 +27,7 @@ struct VulkanModule /// Initialize Slang::Result init(); /// Destroy - void destroy(); + void destroy(); /// Dtor ~VulkanModule() { destroy(); } diff --git a/tools/render-test/vk-swap-chain.cpp b/tools/slang-graphics/vk-swap-chain.cpp index 7b8b6221c..a6704e9d7 100644 --- a/tools/render-test/vk-swap-chain.cpp +++ b/tools/slang-graphics/vk-swap-chain.cpp @@ -8,7 +8,7 @@ #include <stdlib.h> #include <stdio.h> -namespace renderer_test { +namespace slang_graphics { using namespace Slang; static int _indexOf(List<VkSurfaceFormatKHR>& formatsIn, VkFormat format) @@ -32,7 +32,7 @@ SlangResult VulkanSwapChain::init(VulkanDeviceQueue* deviceQueue, const Desc& de m_deviceQueue = deviceQueue; m_api = deviceQueue->getApi(); - + // Make sure it's not set initially m_format = VK_FORMAT_UNDEFINED; @@ -54,9 +54,9 @@ SlangResult VulkanSwapChain::init(VulkanDeviceQueue* deviceQueue, const Desc& de VkXlibSurfaceCreateInfoKHR surfaceCreateInfo = {}; surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; - surfaceCreateInfo.dpy = platformDesc->m_display; + surfaceCreateInfo.dpy = platformDesc->m_display; surfaceCreateInfo.window = platformDesc->m_window; - + SLANG_VK_RETURN_ON_FAIL(m_api->vkCreateXlibSurfaceKHR(m_api->m_instance, &surfaceCreateInfo, nullptr, &m_surface)); #endif @@ -113,7 +113,7 @@ void VulkanSwapChain::getWindowSize(int* widthOut, int* heightOut) const #else auto platformDesc = _getPlatformDesc<XPlatformDesc>(); - XWindowAttributes winAttr = {}; + XWindowAttributes winAttr = {}; XGetWindowAttributes(platformDesc->m_display, platformDesc->m_window, &winAttr); *widthOut = winAttr.width; @@ -128,7 +128,7 @@ SlangResult VulkanSwapChain::_createFrameBuffers(VkRenderPass renderPass) for (int i = 0; i < int(m_images.Count()); ++i) { Image& image = m_images[i]; - VkImageView attachments[] = + VkImageView attachments[] = { image.m_imageView }; @@ -183,7 +183,7 @@ SlangResult VulkanSwapChain::_createSwapChain() return SLANG_OK; } - int width, height; + int width, height; getWindowSize(&width, &height); VkExtent2D imageExtent = {}; @@ -231,8 +231,8 @@ SlangResult VulkanSwapChain::_createSwapChain() { m_presentMode = presentOptions[j]; break; - } - } + } + } if (m_presentMode == VK_PRESENT_MODE_MAX_ENUM_KHR) { @@ -262,29 +262,29 @@ SlangResult VulkanSwapChain::_createSwapChain() uint32_t numSwapChainImages = 0; m_api->vkGetSwapchainImagesKHR(m_api->m_device, m_swapChain, &numSwapChainImages, nullptr); - + { List<VkImage> images; images.SetSize(numSwapChainImages); m_api->vkGetSwapchainImagesKHR(m_api->m_device, m_swapChain, &numSwapChainImages, images.Buffer()); - + m_images.SetSize(numSwapChainImages); for (int i = 0; i < int(numSwapChainImages); ++i) { Image& dstImage = m_images[i]; dstImage.m_image = images[i]; - + } } { VkImageViewCreateInfo createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - + createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; createInfo.format = m_format; - + createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; @@ -301,7 +301,7 @@ SlangResult VulkanSwapChain::_createSwapChain() Image& image = m_images[i]; createInfo.image = image.m_image; - + SLANG_VK_RETURN_ON_FAIL(m_api->vkCreateImageView(m_api->m_device, &createInfo, nullptr, &image.m_imageView)); } } @@ -318,7 +318,7 @@ void VulkanSwapChain::_destroySwapChain() { if (!hasValidSwapChain()) { - return; + return; } m_deviceQueue->waitForIdle(); @@ -351,7 +351,7 @@ void VulkanSwapChain::_destroySwapChain() VulkanSwapChain::~VulkanSwapChain() { _destroySwapChain(); - + if (m_surface) { m_api->vkDestroySurfaceKHR(m_api->m_instance, m_surface, nullptr); @@ -370,7 +370,7 @@ int VulkanSwapChain::nextFrontImageIndex() } VkSemaphore beginFrameSemaphore = m_deviceQueue->makeCurrent(VulkanDeviceQueue::EventType::BeginFrame); - + uint32_t swapChainIndex = 0; VkResult result = m_api->vkAcquireNextImageKHR(m_api->m_device, m_swapChain, UINT64_MAX, beginFrameSemaphore, VK_NULL_HANDLE, &swapChainIndex); @@ -392,15 +392,15 @@ void VulkanSwapChain::present(bool vsync) } VkSemaphore endFrameSemaphore = m_deviceQueue->makeCurrent(VulkanDeviceQueue::EventType::EndFrame); - + m_deviceQueue->flushStepA(); - + uint32_t swapChainIndices[] = { uint32_t(m_currentSwapChainIndex) }; VkPresentInfoKHR presentInfo = {}; presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfo.swapchainCount = 1; - presentInfo.pSwapchains = &m_swapChain; + presentInfo.pSwapchains = &m_swapChain; presentInfo.pImageIndices = swapChainIndices; presentInfo.waitSemaphoreCount = 1; presentInfo.pWaitSemaphores = &endFrameSemaphore; @@ -408,9 +408,9 @@ void VulkanSwapChain::present(bool vsync) VkResult result = m_api->vkQueuePresentKHR(m_deviceQueue->getQueue(), &presentInfo); m_deviceQueue->makeCompleted(VulkanDeviceQueue::EventType::EndFrame); - + m_deviceQueue->flushStepB(); - + if (result != VK_SUCCESS || m_vsync != vsync) { m_vsync = vsync; diff --git a/tools/render-test/vk-swap-chain.h b/tools/slang-graphics/vk-swap-chain.h index 2c9fb588d..7c04af70c 100644 --- a/tools/render-test/vk-swap-chain.h +++ b/tools/slang-graphics/vk-swap-chain.h @@ -8,11 +8,11 @@ #include "../../source/core/list.h" -namespace renderer_test { +namespace slang_graphics { struct VulkanSwapChain { - /* enum + /* enum { kMaxImages = 8, }; */ @@ -31,7 +31,7 @@ struct VulkanSwapChain #else struct XPlatformDesc : public PlatformDesc { - Display* m_display; + Display* m_display; Window m_window; }; #endif @@ -67,7 +67,7 @@ struct VulkanSwapChain /// Create the frame buffers (they must be compatible with the supplied renderPass) SlangResult createFrameBuffers(VkRenderPass renderPass); - /// Returned the desc used to construct the swap chain. + /// Returned the desc used to construct the swap chain. /// Is invalid if init hasn't returned with successful result. const Desc& getDesc() const { return m_desc; } @@ -99,7 +99,7 @@ struct VulkanSwapChain protected: - + template <typename T> void _setPlatformDesc(const T& desc) { @@ -129,7 +129,7 @@ struct VulkanSwapChain int m_currentSwapChainIndex = 0; - Slang::List<Image> m_images; + Slang::List<Image> m_images; VulkanDeviceQueue* m_deviceQueue = nullptr; const VulkanApi* m_api = nullptr; diff --git a/tools/render-test/vk-util.cpp b/tools/slang-graphics/vk-util.cpp index 925001144..374a3876d 100644 --- a/tools/render-test/vk-util.cpp +++ b/tools/slang-graphics/vk-util.cpp @@ -4,7 +4,7 @@ #include <stdlib.h> #include <stdio.h> -namespace renderer_test { +namespace slang_graphics { /* static */VkFormat VulkanUtil::getVkFormat(Format format) { diff --git a/tools/render-test/vk-util.h b/tools/slang-graphics/vk-util.h index 2d98a1c0f..420c0a57a 100644 --- a/tools/render-test/vk-util.h +++ b/tools/slang-graphics/vk-util.h @@ -12,10 +12,10 @@ #define SLANG_VK_RETURN_NULL_ON_FAIL(x) { VkResult _res = x; if (_res != VK_SUCCESS) { VulkanUtil::handleFail(_res); return nullptr; } } -/// Is similar to SLANG_VK_RETURN_ON_FAIL, but does not return. Will call checkFail on failure - which asserts on debug builds. -#define SLANG_VK_CHECK(x) { VkResult _res = x; if (_res != VK_SUCCESS) { VulkanUtil::checkFail(_res); } } - -namespace renderer_test { +/// Is similar to SLANG_VK_RETURN_ON_FAIL, but does not return. Will call checkFail on failure - which asserts on debug builds. +#define SLANG_VK_CHECK(x) { VkResult _res = x; if (_res != VK_SUCCESS) { VulkanUtil::checkFail(_res); } } + +namespace slang_graphics { // Utility functions for Vulkan struct VulkanUtil @@ -24,17 +24,17 @@ struct VulkanUtil /// Returns VK_FORMAT_UNDEFINED if a match is not found static VkFormat getVkFormat(Format format); - /// Called by SLANG_VK_RETURN_FAIL if a res is a failure. + /// Called by SLANG_VK_RETURN_FAIL if a res is a failure. /// On debug builds this will cause an assertion on failure. static Slang::Result handleFail(VkResult res); /// Called when a failure has occurred with SLANG_VK_CHECK - will typically assert. static void checkFail(VkResult res); - /// Get the VkPrimitiveTopology for the given topology. + /// Get the VkPrimitiveTopology for the given topology. /// Returns VK_PRIMITIVE_TOPOLOGY_MAX_ENUM on failure static VkPrimitiveTopology getVkPrimitiveTopology(PrimitiveTopology topology); - /// Returns Slang::Result equivalent of a VkResult + /// Returns Slang::Result equivalent of a VkResult static Slang::Result toSlangResult(VkResult res); }; diff --git a/tools/slang-graphics/window.cpp b/tools/slang-graphics/window.cpp new file mode 100644 index 000000000..7aef88c12 --- /dev/null +++ b/tools/slang-graphics/window.cpp @@ -0,0 +1,245 @@ +// window.cpp +#include "window.h" +#pragma once + +#include <stdio.h> + +#ifdef _MSC_VER +#include <stddef.h> +#if (_MSC_VER < 1900) +#define snprintf sprintf_s +#endif +#endif + + +#if _WIN32 +#include <Windows.h> +#else +#error "The slang-graphics library currently only supports Windows platforms" +#endif + +namespace slang_graphics { + +#if _WIN32 + +struct OSString +{ + OSString(char const* begin, char const* end) + { + _initialize(begin, end - begin); + } + + OSString(char const* begin) + { + _initialize(begin, strlen(begin)); + } + + ~OSString() + { + free(mBegin); + } + + operator WCHAR const*() + { + return mBegin; + } + +private: + WCHAR* mBegin; + WCHAR* mEnd; + + void _initialize(char const* input, size_t inputSize) + { + const DWORD dwFlags = 0; + int outputCodeUnitCount = ::MultiByteToWideChar(CP_UTF8, dwFlags, input, int(inputSize), nullptr, 0); + + WCHAR* buffer = (WCHAR*)malloc(sizeof(WCHAR) * (outputCodeUnitCount + 1)); + + ::MultiByteToWideChar(CP_UTF8, dwFlags, input, int(inputSize), buffer, outputCodeUnitCount); + buffer[outputCodeUnitCount] = 0; + + mBegin = buffer; + mEnd = buffer + outputCodeUnitCount; + } +}; + +struct ApplicationContext +{ + HINSTANCE instance; + int showCommand = SW_SHOWDEFAULT; + int resultCode = 0; +}; + +/// Run an application given the specified callback and command-line arguments. +int runApplication( + ApplicationFunc func, + int argc, + char const* const* argv) +{ + ApplicationContext context; + context.instance = (HINSTANCE) GetModuleHandle(0); + func(&context); + return context.resultCode; +} + +int runWindowsApplication( + ApplicationFunc func, + void* instance, + int showCommand) +{ + ApplicationContext context; + context.instance = (HINSTANCE) instance; + context.showCommand = showCommand; + func(&context); + return context.resultCode; +} + +struct Window +{ + HWND handle; +}; + +static LRESULT CALLBACK windowProc( + HWND windowHandle, + UINT message, + WPARAM wParam, + LPARAM lParam) +{ + // TODO: Actually implement some reasonable logic here. + switch (message) + { + case WM_CLOSE: + PostQuitMessage(0); + return 0; + } + + return DefWindowProcW(windowHandle, message, wParam, lParam); +} + + +static ATOM createWindowClassAtom() +{ + WNDCLASSEXW windowClassDesc; + windowClassDesc.cbSize = sizeof(windowClassDesc); + windowClassDesc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; + windowClassDesc.lpfnWndProc = &windowProc; + windowClassDesc.cbClsExtra = 0; + windowClassDesc.cbWndExtra = 0; + windowClassDesc.hInstance = (HINSTANCE) GetModuleHandle(0); + windowClassDesc.hIcon = 0; + windowClassDesc.hCursor = 0; + windowClassDesc.hbrBackground = 0; + windowClassDesc.lpszMenuName = 0; + windowClassDesc.lpszClassName = L"SlangGraphicsWindow"; + windowClassDesc.hIconSm = 0; + ATOM windowClassAtom = RegisterClassExW(&windowClassDesc); + return windowClassAtom; +} + +static ATOM getWindowClassAtom() +{ + static ATOM windowClassAtom = createWindowClassAtom(); + return windowClassAtom; +} + +Window* createWindow(WindowDesc const& desc) +{ + Window* window = new Window(); + + OSString windowTitle(desc.title); + + DWORD windowExtendedStyle = 0; + DWORD windowStyle = 0; + + HINSTANCE instance = (HINSTANCE) GetModuleHandle(0); + + HWND windowHandle = CreateWindowExW( + windowExtendedStyle, + (LPWSTR) getWindowClassAtom(), + windowTitle, + windowStyle, + 0, 0, // x, y + desc.width, desc.height, + NULL, // parent + NULL, // menu + instance, + window); + + if(!windowHandle) + { + delete window; + return nullptr; + } + + window->handle = windowHandle; + return window; +} + +void showWindow(Window* window) +{ + ShowWindow(window->handle, SW_SHOW); +} + +void* getPlatformWindowHandle(Window* window) +{ + return window->handle; +} + +bool dispatchEvents(ApplicationContext* context) +{ + for(;;) + { + MSG message; + + int result = PeekMessageW(&message, NULL, 0, 0, PM_REMOVE); + if (result != 0) + { + if (message.message == WM_QUIT) + { + context->resultCode = (int)message.wParam; + return false; + } + + TranslateMessage(&message); + DispatchMessageW(&message); + } + else + { + return true; + } + } + +} + +void exitApplication(ApplicationContext* context, int resultCode) +{ + ExitProcess(resultCode); +} + +int reportError(char const* message, ...) +{ + va_list args; + va_start(args, message); + + static const int kBufferSize = 1024; + char messageBuffer[kBufferSize]; + vsnprintf(messageBuffer, kBufferSize - 1, message, args); + messageBuffer[kBufferSize - 1] = 0; + + va_end(args); + + fputs(messageBuffer, stderr); + + OSString wideMessageBuffer(messageBuffer); + OutputDebugStringW(wideMessageBuffer); + + return 1; +} + +#else + +// TODO: put an SDL version here + +#endif + +} // slang_graphics diff --git a/tools/slang-graphics/window.h b/tools/slang-graphics/window.h new file mode 100644 index 000000000..91c8286d5 --- /dev/null +++ b/tools/slang-graphics/window.h @@ -0,0 +1,69 @@ +// window.h +#pragma once + +namespace slang_graphics { + +struct WindowDesc +{ + char const* title; + int width; + int height; +}; + +typedef struct Window Window; + +Window* createWindow(WindowDesc const& desc); +void showWindow(Window* window); +void* getPlatformWindowHandle(Window* window); + +/// Opaque state provided by platform for a running application. +typedef struct ApplicationContext ApplicationContext; + +/// User-defined application entry-point function. +typedef void(*ApplicationFunc)(ApplicationContext* context); + +/// Dispatch any pending events for application. +/// +/// @returns `true` if application should keep running. +bool dispatchEvents(ApplicationContext* context); + +/// Exit the application with a given result code +void exitApplication(ApplicationContext* context, int resultCode); + +/// Report an error to an appropriate logging destination. +int reportError(char const* message, ...); + +/// Run an application given the specified callback and command-line arguments. +int runApplication( + ApplicationFunc func, + int argc, + char const* const* argv); + +#define SG_CONSOLE_MAIN(APPLICATION_ENTRY) \ + int main(int argc, char** argv) { \ + return slang_graphics::runApplication(&(APPLIATION_ENTRY), argc, argv); \ + } + +#ifdef _WIN32 + +int runWindowsApplication( + ApplicationFunc func, + void* instance, + int showCommand); + +#define SG_UI_MAIN(APPLICATION_ENTRY) \ + int __stdcall WinMain( \ + void* instance, \ + void* /* prevInstance */, \ + void* /* commandLine */, \ + int showCommand) { \ + return slang_graphics::runWindowsApplication(&(APPLICATION_ENTRY), instance, showCommand); \ + } + +#else + +#define SG_UI_MAIN(APPLICATION_ENTRY) SG_CONSOLE_MAIN(APPLICATION_ENTRY) + +#endif + +} // slang_graphics |
