fix formatting

This commit is contained in:
Austin Eng 2017-05-30 20:03:44 -04:00 committed by Corentin Wallez
parent 084346bd5f
commit 376f1c6a8e
20 changed files with 3453 additions and 3453 deletions

View File

@ -1,79 +1,79 @@
# Copyright 2017 The NXT Authors # Copyright 2017 The NXT Authors
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
# You may obtain a copy of the License at # You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
list(APPEND UTILS_SOURCES list(APPEND UTILS_SOURCES
Utils.h Utils.h
Utils.cpp Utils.cpp
BackendBinding.h BackendBinding.h
) )
if (APPLE) if (APPLE)
list(APPEND UTILS_SOURCES list(APPEND UTILS_SOURCES
MetalBinding.mm MetalBinding.mm
) )
endif() endif()
add_library(utils STATIC ${UTILS_SOURCES}) add_library(utils STATIC ${UTILS_SOURCES})
target_link_libraries(utils nxt_backend nxt_wire shaderc nxtcpp nxt) target_link_libraries(utils nxt_backend nxt_wire shaderc nxtcpp nxt)
SetCXX14(utils) SetCXX14(utils)
add_executable(CHelloTriangle HelloTriangle.c) add_executable(CHelloTriangle HelloTriangle.c)
target_link_libraries(CHelloTriangle utils) target_link_libraries(CHelloTriangle utils)
add_executable(CppHelloTriangle HelloTriangle.cpp) add_executable(CppHelloTriangle HelloTriangle.cpp)
target_link_libraries(CppHelloTriangle utils) target_link_libraries(CppHelloTriangle utils)
SetCXX14(CppHelloTriangle) SetCXX14(CppHelloTriangle)
add_executable(ComputeBoids ComputeBoids.cpp) add_executable(ComputeBoids ComputeBoids.cpp)
target_link_libraries(ComputeBoids utils) target_link_libraries(ComputeBoids utils)
target_include_directories(ComputeBoids PUBLIC ../ ${GLM_INCLUDE_DIR}) target_include_directories(ComputeBoids PUBLIC ../ ${GLM_INCLUDE_DIR})
SetCXX14(ComputeBoids) SetCXX14(ComputeBoids)
add_executable(HelloVertices HelloVertices.cpp) add_executable(HelloVertices HelloVertices.cpp)
target_link_libraries(HelloVertices utils) target_link_libraries(HelloVertices utils)
SetCXX14(HelloVertices) SetCXX14(HelloVertices)
add_executable(HelloInstancing HelloInstancing.cpp) add_executable(HelloInstancing HelloInstancing.cpp)
target_link_libraries(HelloInstancing utils) target_link_libraries(HelloInstancing utils)
SetCXX14(HelloInstancing) SetCXX14(HelloInstancing)
add_executable(HelloIndices HelloIndices.cpp) add_executable(HelloIndices HelloIndices.cpp)
target_link_libraries(HelloIndices utils) target_link_libraries(HelloIndices utils)
SetCXX14(HelloIndices) SetCXX14(HelloIndices)
add_executable(HelloUBO HelloUBO.cpp) add_executable(HelloUBO HelloUBO.cpp)
target_link_libraries(HelloUBO utils) target_link_libraries(HelloUBO utils)
SetCXX14(HelloUBO) SetCXX14(HelloUBO)
add_executable(HelloCompute HelloCompute.cpp) add_executable(HelloCompute HelloCompute.cpp)
target_link_libraries(HelloCompute utils) target_link_libraries(HelloCompute utils)
SetCXX14(HelloCompute) SetCXX14(HelloCompute)
add_executable(RenderToTexture RenderToTexture.cpp) add_executable(RenderToTexture RenderToTexture.cpp)
target_link_libraries(RenderToTexture utils) target_link_libraries(RenderToTexture utils)
SetCXX14(RenderToTexture) SetCXX14(RenderToTexture)
add_executable(Animometer Animometer.cpp) add_executable(Animometer Animometer.cpp)
target_link_libraries(Animometer utils) target_link_libraries(Animometer utils)
SetCXX14(Animometer) SetCXX14(Animometer)
add_executable(SpirvTest SpirvTest.cpp) add_executable(SpirvTest SpirvTest.cpp)
target_link_libraries(SpirvTest shaderc spirv-cross nxtcpp) target_link_libraries(SpirvTest shaderc spirv-cross nxtcpp)
SetCXX14(SpirvTest) SetCXX14(SpirvTest)
add_executable(CppHelloDepthStencil HelloDepthStencil.cpp) add_executable(CppHelloDepthStencil HelloDepthStencil.cpp)
target_link_libraries(CppHelloDepthStencil utils) target_link_libraries(CppHelloDepthStencil utils)
SetCXX14(CppHelloDepthStencil) SetCXX14(CppHelloDepthStencil)
add_subdirectory(glTFViewer) add_subdirectory(glTFViewer)

View File

@ -1,352 +1,352 @@
// Copyright 2017 The NXT Authors // Copyright 2017 The NXT Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "Utils.h" #include "Utils.h"
#include <vector> #include <vector>
#include <glm/glm/glm.hpp> #include <glm/glm/glm.hpp>
#include <glm/glm/gtc/matrix_transform.hpp> #include <glm/glm/gtc/matrix_transform.hpp>
#include <glm/glm/gtc/type_ptr.hpp> #include <glm/glm/gtc/type_ptr.hpp>
nxt::Device device; nxt::Device device;
nxt::Buffer indexBuffer; nxt::Buffer indexBuffer;
nxt::Buffer vertexBuffer; nxt::Buffer vertexBuffer;
nxt::Buffer planeBuffer; nxt::Buffer planeBuffer;
nxt::Buffer cameraBuffer; nxt::Buffer cameraBuffer;
nxt::Buffer transformBuffer[2]; nxt::Buffer transformBuffer[2];
nxt::BindGroup cameraBindGroup; nxt::BindGroup cameraBindGroup;
nxt::BindGroup bindGroup[2]; nxt::BindGroup bindGroup[2];
nxt::BindGroup cubeTransformBindGroup[2]; nxt::BindGroup cubeTransformBindGroup[2];
nxt::Queue queue; nxt::Queue queue;
nxt::Pipeline pipeline; nxt::Pipeline pipeline;
nxt::Pipeline planePipeline; nxt::Pipeline planePipeline;
nxt::Pipeline reflectionPipeline; nxt::Pipeline reflectionPipeline;
nxt::RenderPass renderpass; nxt::RenderPass renderpass;
nxt::Framebuffer framebuffer; nxt::Framebuffer framebuffer;
void initBuffers() { void initBuffers() {
static const uint32_t indexData[6*6] = { static const uint32_t indexData[6*6] = {
0, 1, 2, 0, 1, 2,
0, 2, 3, 0, 2, 3,
4, 5, 6, 4, 5, 6,
4, 6, 7, 4, 6, 7,
8, 9, 10, 8, 9, 10,
8, 10, 11, 8, 10, 11,
12, 13, 14, 12, 13, 14,
12, 14, 15, 12, 14, 15,
16, 17, 18, 16, 17, 18,
16, 18, 19, 16, 18, 19,
20, 21, 22, 20, 21, 22,
20, 22, 23 20, 22, 23
}; };
indexBuffer = device.CreateBufferBuilder() indexBuffer = device.CreateBufferBuilder()
.SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Index) .SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Index)
.SetInitialUsage(nxt::BufferUsageBit::Mapped) .SetInitialUsage(nxt::BufferUsageBit::Mapped)
.SetSize(sizeof(indexData)) .SetSize(sizeof(indexData))
.GetResult(); .GetResult();
indexBuffer.SetSubData(0, sizeof(indexData) / sizeof(uint32_t), indexData); indexBuffer.SetSubData(0, sizeof(indexData) / sizeof(uint32_t), indexData);
indexBuffer.FreezeUsage(nxt::BufferUsageBit::Index); indexBuffer.FreezeUsage(nxt::BufferUsageBit::Index);
static const float vertexData[6 * 4 * 6] = { static const float vertexData[6 * 4 * 6] = {
-1.0, -1.0, 1.0, 1.0, 0.0, 0.0, -1.0, -1.0, 1.0, 1.0, 0.0, 0.0,
1.0, -1.0, 1.0, 1.0, 0.0, 0.0, 1.0, -1.0, 1.0, 1.0, 0.0, 0.0,
1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
-1.0, 1.0, 1.0, 1.0, 0.0, 0.0, -1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
-1.0, -1.0, -1.0, 1.0, 1.0, 0.0, -1.0, -1.0, -1.0, 1.0, 1.0, 0.0,
-1.0, 1.0, -1.0, 1.0, 1.0, 0.0, -1.0, 1.0, -1.0, 1.0, 1.0, 0.0,
1.0, 1.0, -1.0, 1.0, 1.0, 0.0, 1.0, 1.0, -1.0, 1.0, 1.0, 0.0,
1.0, -1.0, -1.0, 1.0, 1.0, 0.0, 1.0, -1.0, -1.0, 1.0, 1.0, 0.0,
-1.0, 1.0, -1.0, 1.0, 0.0, 1.0, -1.0, 1.0, -1.0, 1.0, 0.0, 1.0,
-1.0, 1.0, 1.0, 1.0, 0.0, 1.0, -1.0, 1.0, 1.0, 1.0, 0.0, 1.0,
1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0,
1.0, 1.0, -1.0, 1.0, 0.0, 1.0, 1.0, 1.0, -1.0, 1.0, 0.0, 1.0,
-1.0, -1.0, -1.0, 0.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0, 1.0, 0.0,
1.0, -1.0, -1.0, 0.0, 1.0, 0.0, 1.0, -1.0, -1.0, 0.0, 1.0, 0.0,
1.0, -1.0, 1.0, 0.0, 1.0, 0.0, 1.0, -1.0, 1.0, 0.0, 1.0, 0.0,
-1.0, -1.0, 1.0, 0.0, 1.0, 0.0, -1.0, -1.0, 1.0, 0.0, 1.0, 0.0,
1.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, -1.0, -1.0, 0.0, 1.0, 1.0,
1.0, 1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 1.0, -1.0, 0.0, 1.0, 1.0,
1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 1.0,
1.0, -1.0, 1.0, 0.0, 1.0, 1.0, 1.0, -1.0, 1.0, 0.0, 1.0, 1.0,
-1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0,
-1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0,
-1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
-1.0, 1.0, -1.0, 1.0, 1.0, 1.0 -1.0, 1.0, -1.0, 1.0, 1.0, 1.0
}; };
vertexBuffer = device.CreateBufferBuilder() vertexBuffer = device.CreateBufferBuilder()
.SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Vertex) .SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Vertex)
.SetInitialUsage(nxt::BufferUsageBit::Mapped) .SetInitialUsage(nxt::BufferUsageBit::Mapped)
.SetSize(sizeof(vertexData)) .SetSize(sizeof(vertexData))
.GetResult(); .GetResult();
vertexBuffer.SetSubData(0, sizeof(vertexData) / sizeof(uint32_t), vertexBuffer.SetSubData(0, sizeof(vertexData) / sizeof(uint32_t),
reinterpret_cast<const uint32_t*>(vertexData)); reinterpret_cast<const uint32_t*>(vertexData));
vertexBuffer.FreezeUsage(nxt::BufferUsageBit::Vertex); vertexBuffer.FreezeUsage(nxt::BufferUsageBit::Vertex);
static const float planeData[6 * 4] = { static const float planeData[6 * 4] = {
-2.0, -1.0, -2.0, 0.5, 0.5, 0.5, -2.0, -1.0, -2.0, 0.5, 0.5, 0.5,
2.0, -1.0, -2.0, 0.5, 0.5, 0.5, 2.0, -1.0, -2.0, 0.5, 0.5, 0.5,
2.0, -1.0, 2.0, 0.5, 0.5, 0.5, 2.0, -1.0, 2.0, 0.5, 0.5, 0.5,
-2.0, -1.0, 2.0, 0.5, 0.5, 0.5, -2.0, -1.0, 2.0, 0.5, 0.5, 0.5,
}; };
planeBuffer = device.CreateBufferBuilder() planeBuffer = device.CreateBufferBuilder()
.SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Vertex) .SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Vertex)
.SetInitialUsage(nxt::BufferUsageBit::Mapped) .SetInitialUsage(nxt::BufferUsageBit::Mapped)
.SetSize(sizeof(planeData)) .SetSize(sizeof(planeData))
.GetResult(); .GetResult();
planeBuffer.SetSubData(0, sizeof(planeData) / sizeof(uint32_t), planeBuffer.SetSubData(0, sizeof(planeData) / sizeof(uint32_t),
reinterpret_cast<const uint32_t*>(planeData)); reinterpret_cast<const uint32_t*>(planeData));
planeBuffer.FreezeUsage(nxt::BufferUsageBit::Vertex); planeBuffer.FreezeUsage(nxt::BufferUsageBit::Vertex);
} }
struct { struct {
glm::mat4 view; glm::mat4 view;
glm::mat4 proj; glm::mat4 proj;
} cameraData; } cameraData;
void init() { void init() {
device = CreateCppNXTDevice(); device = CreateCppNXTDevice();
queue = device.CreateQueueBuilder().GetResult(); queue = device.CreateQueueBuilder().GetResult();
initBuffers(); initBuffers();
nxt::ShaderModule vsModule = CreateShaderModule(device, nxt::ShaderStage::Vertex, R"( nxt::ShaderModule vsModule = CreateShaderModule(device, nxt::ShaderStage::Vertex, R"(
#version 450 #version 450
layout(set = 0, binding = 0) uniform cameraData { layout(set = 0, binding = 0) uniform cameraData {
mat4 view; mat4 view;
mat4 proj; mat4 proj;
} camera; } camera;
layout(set = 0, binding = 1) uniform modelData { layout(set = 0, binding = 1) uniform modelData {
mat4 modelMatrix; mat4 modelMatrix;
}; };
layout(location = 0) in vec3 pos; layout(location = 0) in vec3 pos;
layout(location = 1) in vec3 col; layout(location = 1) in vec3 col;
layout(location = 2) out vec3 f_col; layout(location = 2) out vec3 f_col;
void main() { void main() {
f_col = col; f_col = col;
gl_Position = camera.proj * camera.view * modelMatrix * vec4(pos, 1.0); gl_Position = camera.proj * camera.view * modelMatrix * vec4(pos, 1.0);
})" })"
); );
nxt::ShaderModule fsModule = CreateShaderModule(device, nxt::ShaderStage::Fragment, R"( nxt::ShaderModule fsModule = CreateShaderModule(device, nxt::ShaderStage::Fragment, R"(
#version 450 #version 450
layout(location = 2) in vec3 f_col; layout(location = 2) in vec3 f_col;
out vec4 fragColor; out vec4 fragColor;
void main() { void main() {
fragColor = vec4(f_col, 1.0); fragColor = vec4(f_col, 1.0);
})" })"
); );
nxt::ShaderModule fsReflectionModule = CreateShaderModule(device, nxt::ShaderStage::Fragment, R"( nxt::ShaderModule fsReflectionModule = CreateShaderModule(device, nxt::ShaderStage::Fragment, R"(
#version 450 #version 450
layout(location = 2) in vec3 f_col; layout(location = 2) in vec3 f_col;
out vec4 fragColor; out vec4 fragColor;
void main() { void main() {
fragColor = vec4(mix(f_col, vec3(0.5, 0.5, 0.5), 0.5), 1.0); fragColor = vec4(mix(f_col, vec3(0.5, 0.5, 0.5), 0.5), 1.0);
})" })"
); );
auto inputState = device.CreateInputStateBuilder() auto inputState = device.CreateInputStateBuilder()
.SetAttribute(0, 0, nxt::VertexFormat::FloatR32G32B32, 0) .SetAttribute(0, 0, nxt::VertexFormat::FloatR32G32B32, 0)
.SetAttribute(1, 0, nxt::VertexFormat::FloatR32G32B32, 3 * sizeof(float)) .SetAttribute(1, 0, nxt::VertexFormat::FloatR32G32B32, 3 * sizeof(float))
.SetInput(0, 6 * sizeof(float), nxt::InputStepMode::Vertex) .SetInput(0, 6 * sizeof(float), nxt::InputStepMode::Vertex)
.SetInput(1, 6 * sizeof(float), nxt::InputStepMode::Vertex) .SetInput(1, 6 * sizeof(float), nxt::InputStepMode::Vertex)
.GetResult(); .GetResult();
nxt::BindGroupLayout bgl = device.CreateBindGroupLayoutBuilder() nxt::BindGroupLayout bgl = device.CreateBindGroupLayoutBuilder()
.SetBindingsType(nxt::ShaderStageBit::Vertex, nxt::BindingType::UniformBuffer, 0, 2) .SetBindingsType(nxt::ShaderStageBit::Vertex, nxt::BindingType::UniformBuffer, 0, 2)
.GetResult(); .GetResult();
nxt::PipelineLayout pl = device.CreatePipelineLayoutBuilder() nxt::PipelineLayout pl = device.CreatePipelineLayoutBuilder()
.SetBindGroupLayout(0, bgl) .SetBindGroupLayout(0, bgl)
.GetResult(); .GetResult();
cameraBuffer = device.CreateBufferBuilder() cameraBuffer = device.CreateBufferBuilder()
.SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Uniform) .SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Uniform)
.SetInitialUsage(nxt::BufferUsageBit::Mapped) .SetInitialUsage(nxt::BufferUsageBit::Mapped)
.SetSize(sizeof(cameraData)) .SetSize(sizeof(cameraData))
.GetResult(); .GetResult();
glm::mat4 transform(1.0); glm::mat4 transform(1.0);
transformBuffer[0] = device.CreateBufferBuilder() transformBuffer[0] = device.CreateBufferBuilder()
.SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Uniform) .SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Uniform)
.SetInitialUsage(nxt::BufferUsageBit::Mapped) .SetInitialUsage(nxt::BufferUsageBit::Mapped)
.SetSize(sizeof(glm::mat4)) .SetSize(sizeof(glm::mat4))
.GetResult(); .GetResult();
transformBuffer[0].SetSubData(0, sizeof(glm::mat4) / sizeof(uint32_t), reinterpret_cast<uint32_t*>(&transform)); transformBuffer[0].SetSubData(0, sizeof(glm::mat4) / sizeof(uint32_t), reinterpret_cast<uint32_t*>(&transform));
transformBuffer[0].FreezeUsage(nxt::BufferUsageBit::Uniform); transformBuffer[0].FreezeUsage(nxt::BufferUsageBit::Uniform);
transform = glm::translate(transform, glm::vec3(0.f, -2.f, 0.f)); transform = glm::translate(transform, glm::vec3(0.f, -2.f, 0.f));
transformBuffer[1] = device.CreateBufferBuilder() transformBuffer[1] = device.CreateBufferBuilder()
.SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Uniform) .SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Uniform)
.SetInitialUsage(nxt::BufferUsageBit::Mapped) .SetInitialUsage(nxt::BufferUsageBit::Mapped)
.SetSize(sizeof(glm::mat4)) .SetSize(sizeof(glm::mat4))
.GetResult(); .GetResult();
transformBuffer[1].SetSubData(0, sizeof(glm::mat4) / sizeof(uint32_t), reinterpret_cast<uint32_t*>(&transform)); transformBuffer[1].SetSubData(0, sizeof(glm::mat4) / sizeof(uint32_t), reinterpret_cast<uint32_t*>(&transform));
transformBuffer[1].FreezeUsage(nxt::BufferUsageBit::Uniform); transformBuffer[1].FreezeUsage(nxt::BufferUsageBit::Uniform);
nxt::BufferView cameraBufferView = cameraBuffer.CreateBufferViewBuilder() nxt::BufferView cameraBufferView = cameraBuffer.CreateBufferViewBuilder()
.SetExtent(0, sizeof(cameraData)) .SetExtent(0, sizeof(cameraData))
.GetResult(); .GetResult();
nxt::BufferView transformBufferView[2] = { nxt::BufferView transformBufferView[2] = {
transformBuffer[0].CreateBufferViewBuilder() transformBuffer[0].CreateBufferViewBuilder()
.SetExtent(0, sizeof(glm::mat4)) .SetExtent(0, sizeof(glm::mat4))
.GetResult(), .GetResult(),
transformBuffer[1].CreateBufferViewBuilder() transformBuffer[1].CreateBufferViewBuilder()
.SetExtent(0, sizeof(glm::mat4)) .SetExtent(0, sizeof(glm::mat4))
.GetResult(), .GetResult(),
}; };
bindGroup[0] = device.CreateBindGroupBuilder() bindGroup[0] = device.CreateBindGroupBuilder()
.SetLayout(bgl) .SetLayout(bgl)
.SetUsage(nxt::BindGroupUsage::Frozen) .SetUsage(nxt::BindGroupUsage::Frozen)
.SetBufferViews(0, 1, &cameraBufferView) .SetBufferViews(0, 1, &cameraBufferView)
.SetBufferViews(1, 1, &transformBufferView[0]) .SetBufferViews(1, 1, &transformBufferView[0])
.GetResult(); .GetResult();
bindGroup[1] = device.CreateBindGroupBuilder() bindGroup[1] = device.CreateBindGroupBuilder()
.SetLayout(bgl) .SetLayout(bgl)
.SetUsage(nxt::BindGroupUsage::Frozen) .SetUsage(nxt::BindGroupUsage::Frozen)
.SetBufferViews(0, 1, &cameraBufferView) .SetBufferViews(0, 1, &cameraBufferView)
.SetBufferViews(1, 1, &transformBufferView[1]) .SetBufferViews(1, 1, &transformBufferView[1])
.GetResult(); .GetResult();
CreateDefaultRenderPass(device, &renderpass, &framebuffer); CreateDefaultRenderPass(device, &renderpass, &framebuffer);
auto depthStencilState = device.CreateDepthStencilStateBuilder() auto depthStencilState = device.CreateDepthStencilStateBuilder()
.SetDepthEnabled(true) .SetDepthEnabled(true)
.SetStencilEnabled(false) .SetStencilEnabled(false)
.GetResult(); .GetResult();
pipeline = device.CreatePipelineBuilder() pipeline = device.CreatePipelineBuilder()
.SetSubpass(renderpass, 0) .SetSubpass(renderpass, 0)
.SetLayout(pl) .SetLayout(pl)
.SetStage(nxt::ShaderStage::Vertex, vsModule, "main") .SetStage(nxt::ShaderStage::Vertex, vsModule, "main")
.SetStage(nxt::ShaderStage::Fragment, fsModule, "main") .SetStage(nxt::ShaderStage::Fragment, fsModule, "main")
.SetInputState(inputState) .SetInputState(inputState)
.SetDepthStencilState(depthStencilState) .SetDepthStencilState(depthStencilState)
.GetResult(); .GetResult();
auto planeStencilState = device.CreateDepthStencilStateBuilder() auto planeStencilState = device.CreateDepthStencilStateBuilder()
.SetDepthEnabled(true) .SetDepthEnabled(true)
.SetDepthWrite(nxt::DepthWriteMode::Disabled) .SetDepthWrite(nxt::DepthWriteMode::Disabled)
.SetStencilEnabled(true) .SetStencilEnabled(true)
.SetStencilCompareFunction(nxt::Face::Both, nxt::CompareFunction::Always) .SetStencilCompareFunction(nxt::Face::Both, nxt::CompareFunction::Always)
.SetStencilOperation(nxt::Face::Both, nxt::StencilOperation::Keep, nxt::StencilOperation::Keep, nxt::StencilOperation::Replace) .SetStencilOperation(nxt::Face::Both, nxt::StencilOperation::Keep, nxt::StencilOperation::Keep, nxt::StencilOperation::Replace)
.SetStencilMask(nxt::Face::Both, 0xff, 0xff) .SetStencilMask(nxt::Face::Both, 0xff, 0xff)
.GetResult(); .GetResult();
planePipeline = device.CreatePipelineBuilder() planePipeline = device.CreatePipelineBuilder()
.SetSubpass(renderpass, 0) .SetSubpass(renderpass, 0)
.SetLayout(pl) .SetLayout(pl)
.SetStage(nxt::ShaderStage::Vertex, vsModule, "main") .SetStage(nxt::ShaderStage::Vertex, vsModule, "main")
.SetStage(nxt::ShaderStage::Fragment, fsModule, "main") .SetStage(nxt::ShaderStage::Fragment, fsModule, "main")
.SetInputState(inputState) .SetInputState(inputState)
.SetDepthStencilState(planeStencilState) .SetDepthStencilState(planeStencilState)
.GetResult(); .GetResult();
auto reflectionStencilState = device.CreateDepthStencilStateBuilder() auto reflectionStencilState = device.CreateDepthStencilStateBuilder()
.SetDepthEnabled(true) .SetDepthEnabled(true)
.SetDepthWrite(nxt::DepthWriteMode::Enabled) .SetDepthWrite(nxt::DepthWriteMode::Enabled)
.SetStencilEnabled(true) .SetStencilEnabled(true)
.SetStencilCompareFunction(nxt::Face::Both, nxt::CompareFunction::Equal) .SetStencilCompareFunction(nxt::Face::Both, nxt::CompareFunction::Equal)
.SetStencilOperation(nxt::Face::Both, nxt::StencilOperation::Keep, nxt::StencilOperation::Keep, nxt::StencilOperation::Replace) .SetStencilOperation(nxt::Face::Both, nxt::StencilOperation::Keep, nxt::StencilOperation::Keep, nxt::StencilOperation::Replace)
.SetStencilMask(nxt::Face::Both, 0xff, 0x00) .SetStencilMask(nxt::Face::Both, 0xff, 0x00)
.GetResult(); .GetResult();
reflectionPipeline = device.CreatePipelineBuilder() reflectionPipeline = device.CreatePipelineBuilder()
.SetSubpass(renderpass, 0) .SetSubpass(renderpass, 0)
.SetLayout(pl) .SetLayout(pl)
.SetStage(nxt::ShaderStage::Vertex, vsModule, "main") .SetStage(nxt::ShaderStage::Vertex, vsModule, "main")
.SetStage(nxt::ShaderStage::Fragment, fsReflectionModule, "main") .SetStage(nxt::ShaderStage::Fragment, fsReflectionModule, "main")
.SetInputState(inputState) .SetInputState(inputState)
.SetDepthStencilState(reflectionStencilState) .SetDepthStencilState(reflectionStencilState)
.GetResult(); .GetResult();
cameraData.proj = glm::perspective(glm::radians(45.0f), 1.f, 1.0f, 100.0f); cameraData.proj = glm::perspective(glm::radians(45.0f), 1.f, 1.0f, 100.0f);
} }
struct {uint32_t a; float b;} s; struct {uint32_t a; float b;} s;
void frame() { void frame() {
s.a = (s.a + 1) % 256; s.a = (s.a + 1) % 256;
s.b += 0.01; s.b += 0.01;
if (s.b >= 1.0f) {s.b = 0.0f;} if (s.b >= 1.0f) {s.b = 0.0f;}
static const uint32_t vertexBufferOffsets[1] = {0}; static const uint32_t vertexBufferOffsets[1] = {0};
cameraData.view = glm::lookAt( cameraData.view = glm::lookAt(
glm::vec3(8.f * std::sin(glm::radians(s.b * 360.f)), 2.f, 8.f * std::cos(glm::radians(s.b * 360.f))), glm::vec3(8.f * std::sin(glm::radians(s.b * 360.f)), 2.f, 8.f * std::cos(glm::radians(s.b * 360.f))),
glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f) glm::vec3(0.0f, 1.0f, 0.0f)
); );
cameraBuffer.TransitionUsage(nxt::BufferUsageBit::Mapped); cameraBuffer.TransitionUsage(nxt::BufferUsageBit::Mapped);
cameraBuffer.SetSubData(0, sizeof(cameraData) / sizeof(uint32_t), reinterpret_cast<uint32_t*>(&cameraData)); cameraBuffer.SetSubData(0, sizeof(cameraData) / sizeof(uint32_t), reinterpret_cast<uint32_t*>(&cameraData));
nxt::CommandBuffer commands = device.CreateCommandBufferBuilder() nxt::CommandBuffer commands = device.CreateCommandBufferBuilder()
.BeginRenderPass(renderpass, framebuffer) .BeginRenderPass(renderpass, framebuffer)
.SetPipeline(pipeline) .SetPipeline(pipeline)
.TransitionBufferUsage(cameraBuffer, nxt::BufferUsageBit::Uniform) .TransitionBufferUsage(cameraBuffer, nxt::BufferUsageBit::Uniform)
.SetBindGroup(0, bindGroup[0]) .SetBindGroup(0, bindGroup[0])
.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets) .SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets)
.SetIndexBuffer(indexBuffer, 0, nxt::IndexFormat::Uint32) .SetIndexBuffer(indexBuffer, 0, nxt::IndexFormat::Uint32)
.DrawElements(36, 1, 0, 0) .DrawElements(36, 1, 0, 0)
.SetPipeline(planePipeline) .SetPipeline(planePipeline)
.SetStencilReference(0x1, 0x1) .SetStencilReference(0x1, 0x1)
.SetVertexBuffers(0, 1, &planeBuffer, vertexBufferOffsets) .SetVertexBuffers(0, 1, &planeBuffer, vertexBufferOffsets)
.DrawElements(6, 1, 0, 0) .DrawElements(6, 1, 0, 0)
.SetPipeline(reflectionPipeline) .SetPipeline(reflectionPipeline)
.SetStencilReference(0x1, 0x1) .SetStencilReference(0x1, 0x1)
.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets) .SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets)
.SetBindGroup(0, bindGroup[1]) .SetBindGroup(0, bindGroup[1])
.DrawElements(36, 1, 0, 0) .DrawElements(36, 1, 0, 0)
.EndRenderPass() .EndRenderPass()
.GetResult(); .GetResult();
queue.Submit(1, &commands); queue.Submit(1, &commands);
DoSwapBuffers(); DoSwapBuffers();
} }
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
if (!InitUtils(argc, argv)) { if (!InitUtils(argc, argv)) {
return 1; return 1;
} }
init(); init();
while (!ShouldQuit()) { while (!ShouldQuit()) {
frame(); frame();
USleep(16000); USleep(16000);
} }
// TODO release stuff // TODO release stuff
} }

1838
next.json

File diff suppressed because it is too large Load Diff

View File

@ -1,149 +1,149 @@
# Copyright 2017 The NXT Authors # Copyright 2017 The NXT Authors
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
# You may obtain a copy of the License at # You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, software # Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, # distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
set(COMMON_DIR ${CMAKE_CURRENT_SOURCE_DIR}/common) set(COMMON_DIR ${CMAKE_CURRENT_SOURCE_DIR}/common)
set(METAL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/metal) set(METAL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/metal)
set(NULL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/null) set(NULL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/null)
set(OPENGL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/opengl) set(OPENGL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/opengl)
set(TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tests) set(TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/tests)
list(APPEND BACKEND_SOURCES list(APPEND BACKEND_SOURCES
${COMMON_DIR}/BindGroup.cpp ${COMMON_DIR}/BindGroup.cpp
${COMMON_DIR}/BindGroup.h ${COMMON_DIR}/BindGroup.h
${COMMON_DIR}/BindGroupLayout.cpp ${COMMON_DIR}/BindGroupLayout.cpp
${COMMON_DIR}/BindGroupLayout.h ${COMMON_DIR}/BindGroupLayout.h
${COMMON_DIR}/BitSetIterator.h ${COMMON_DIR}/BitSetIterator.h
${COMMON_DIR}/Builder.cpp ${COMMON_DIR}/Builder.cpp
${COMMON_DIR}/Builder.h ${COMMON_DIR}/Builder.h
${COMMON_DIR}/Buffer.cpp ${COMMON_DIR}/Buffer.cpp
${COMMON_DIR}/Buffer.h ${COMMON_DIR}/Buffer.h
${COMMON_DIR}/CommandAllocator.cpp ${COMMON_DIR}/CommandAllocator.cpp
${COMMON_DIR}/CommandAllocator.h ${COMMON_DIR}/CommandAllocator.h
${COMMON_DIR}/CommandBuffer.cpp ${COMMON_DIR}/CommandBuffer.cpp
${COMMON_DIR}/CommandBuffer.h ${COMMON_DIR}/CommandBuffer.h
${COMMON_DIR}/DepthStencilState.cpp ${COMMON_DIR}/DepthStencilState.cpp
${COMMON_DIR}/DepthStencilState.h ${COMMON_DIR}/DepthStencilState.h
${COMMON_DIR}/Device.cpp ${COMMON_DIR}/Device.cpp
${COMMON_DIR}/Device.h ${COMMON_DIR}/Device.h
${COMMON_DIR}/Forward.h ${COMMON_DIR}/Forward.h
${COMMON_DIR}/Framebuffer.cpp ${COMMON_DIR}/Framebuffer.cpp
${COMMON_DIR}/Framebuffer.h ${COMMON_DIR}/Framebuffer.h
${COMMON_DIR}/InputState.cpp ${COMMON_DIR}/InputState.cpp
${COMMON_DIR}/InputState.h ${COMMON_DIR}/InputState.h
${COMMON_DIR}/Math.cpp ${COMMON_DIR}/Math.cpp
${COMMON_DIR}/Math.h ${COMMON_DIR}/Math.h
${COMMON_DIR}/PerStage.cpp ${COMMON_DIR}/PerStage.cpp
${COMMON_DIR}/PerStage.h ${COMMON_DIR}/PerStage.h
${COMMON_DIR}/Pipeline.cpp ${COMMON_DIR}/Pipeline.cpp
${COMMON_DIR}/Pipeline.h ${COMMON_DIR}/Pipeline.h
${COMMON_DIR}/PipelineLayout.cpp ${COMMON_DIR}/PipelineLayout.cpp
${COMMON_DIR}/PipelineLayout.h ${COMMON_DIR}/PipelineLayout.h
${COMMON_DIR}/Queue.cpp ${COMMON_DIR}/Queue.cpp
${COMMON_DIR}/Queue.h ${COMMON_DIR}/Queue.h
${COMMON_DIR}/RenderPass.cpp ${COMMON_DIR}/RenderPass.cpp
${COMMON_DIR}/RenderPass.h ${COMMON_DIR}/RenderPass.h
${COMMON_DIR}/RefCounted.cpp ${COMMON_DIR}/RefCounted.cpp
${COMMON_DIR}/RefCounted.h ${COMMON_DIR}/RefCounted.h
${COMMON_DIR}/Sampler.cpp ${COMMON_DIR}/Sampler.cpp
${COMMON_DIR}/Sampler.h ${COMMON_DIR}/Sampler.h
${COMMON_DIR}/ShaderModule.cpp ${COMMON_DIR}/ShaderModule.cpp
${COMMON_DIR}/ShaderModule.h ${COMMON_DIR}/ShaderModule.h
${COMMON_DIR}/Texture.cpp ${COMMON_DIR}/Texture.cpp
${COMMON_DIR}/Texture.h ${COMMON_DIR}/Texture.h
${COMMON_DIR}/ToBackend.h ${COMMON_DIR}/ToBackend.h
) )
# OpenGL Backend # OpenGL Backend
Generate( Generate(
LIB_NAME opengl_autogen LIB_NAME opengl_autogen
LIB_TYPE STATIC LIB_TYPE STATIC
PRINT_NAME "OpenGL backend autogenerated files" PRINT_NAME "OpenGL backend autogenerated files"
COMMAND_LINE_ARGS COMMAND_LINE_ARGS
${GENERATOR_COMMON_ARGS} ${GENERATOR_COMMON_ARGS}
-T opengl -T opengl
) )
target_link_libraries(opengl_autogen glfw glad nxtcpp) target_link_libraries(opengl_autogen glfw glad nxtcpp)
target_include_directories(opengl_autogen PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(opengl_autogen PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(opengl_autogen PUBLIC ${GENERATED_DIR}) target_include_directories(opengl_autogen PUBLIC ${GENERATED_DIR})
SetCXX14(opengl_autogen) SetCXX14(opengl_autogen)
SetPIC(opengl_autogen) SetPIC(opengl_autogen)
list(APPEND BACKEND_SOURCES list(APPEND BACKEND_SOURCES
${OPENGL_DIR}/CommandBufferGL.cpp ${OPENGL_DIR}/CommandBufferGL.cpp
${OPENGL_DIR}/CommandBufferGL.h ${OPENGL_DIR}/CommandBufferGL.h
${OPENGL_DIR}/OpenGLBackend.cpp ${OPENGL_DIR}/OpenGLBackend.cpp
${OPENGL_DIR}/OpenGLBackend.h ${OPENGL_DIR}/OpenGLBackend.h
${OPENGL_DIR}/PipelineGL.cpp ${OPENGL_DIR}/PipelineGL.cpp
${OPENGL_DIR}/PipelineGL.h ${OPENGL_DIR}/PipelineGL.h
${OPENGL_DIR}/PipelineLayoutGL.cpp ${OPENGL_DIR}/PipelineLayoutGL.cpp
${OPENGL_DIR}/PipelineLayoutGL.h ${OPENGL_DIR}/PipelineLayoutGL.h
${OPENGL_DIR}/SamplerGL.cpp ${OPENGL_DIR}/SamplerGL.cpp
${OPENGL_DIR}/SamplerGL.h ${OPENGL_DIR}/SamplerGL.h
${OPENGL_DIR}/ShaderModuleGL.cpp ${OPENGL_DIR}/ShaderModuleGL.cpp
${OPENGL_DIR}/ShaderModuleGL.h ${OPENGL_DIR}/ShaderModuleGL.h
${OPENGL_DIR}/TextureGL.cpp ${OPENGL_DIR}/TextureGL.cpp
${OPENGL_DIR}/TextureGL.h ${OPENGL_DIR}/TextureGL.h
) )
# Null backend # Null backend
Generate( Generate(
LIB_NAME null_autogen LIB_NAME null_autogen
LIB_TYPE STATIC LIB_TYPE STATIC
PRINT_NAME "Null backend autogenerated files" PRINT_NAME "Null backend autogenerated files"
COMMAND_LINE_ARGS COMMAND_LINE_ARGS
${GENERATOR_COMMON_ARGS} ${GENERATOR_COMMON_ARGS}
-T null -T null
) )
target_link_libraries(null_autogen nxtcpp) target_link_libraries(null_autogen nxtcpp)
target_include_directories(null_autogen PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(null_autogen PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(null_autogen PUBLIC ${GENERATED_DIR}) target_include_directories(null_autogen PUBLIC ${GENERATED_DIR})
SetCXX14(null_autogen) SetCXX14(null_autogen)
SetPIC(null_autogen) SetPIC(null_autogen)
list(APPEND BACKEND_SOURCES list(APPEND BACKEND_SOURCES
${NULL_DIR}/NullBackend.cpp ${NULL_DIR}/NullBackend.cpp
${NULL_DIR}/NullBackend.h ${NULL_DIR}/NullBackend.h
) )
# Metal Backend # Metal Backend
if (APPLE) if (APPLE)
Generate( Generate(
LIB_NAME metal_autogen LIB_NAME metal_autogen
LIB_TYPE STATIC LIB_TYPE STATIC
PRINT_NAME "Metal backend autogenerated files" PRINT_NAME "Metal backend autogenerated files"
COMMAND_LINE_ARGS COMMAND_LINE_ARGS
${GENERATOR_COMMON_ARGS} ${GENERATOR_COMMON_ARGS}
-T metal -T metal
) )
target_link_libraries(metal_autogen glfw glad nxtcpp "-framework QuartzCore" "-framework Metal") target_link_libraries(metal_autogen glfw glad nxtcpp "-framework QuartzCore" "-framework Metal")
target_include_directories(metal_autogen PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(metal_autogen PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(metal_autogen PUBLIC ${GENERATED_DIR}) target_include_directories(metal_autogen PUBLIC ${GENERATED_DIR})
SetCXX14(metal_autogen) SetCXX14(metal_autogen)
SetPIC(metal_autogen) SetPIC(metal_autogen)
list(APPEND BACKEND_SOURCES list(APPEND BACKEND_SOURCES
${METAL_DIR}/MetalBackend.mm ${METAL_DIR}/MetalBackend.mm
${METAL_DIR}/MetalBackend.h ${METAL_DIR}/MetalBackend.h
) )
endif() endif()
add_library(nxt_backend STATIC ${BACKEND_SOURCES}) add_library(nxt_backend STATIC ${BACKEND_SOURCES})
target_link_libraries(nxt_backend opengl_autogen null_autogen glfw glad spirv-cross) target_link_libraries(nxt_backend opengl_autogen null_autogen glfw glad spirv-cross)
if (APPLE) if (APPLE)
target_link_libraries(nxt_backend metal_autogen) target_link_libraries(nxt_backend metal_autogen)
endif() endif()
target_include_directories(nxt_backend PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(nxt_backend PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
SetCXX14(nxt_backend) SetCXX14(nxt_backend)

View File

@ -110,12 +110,12 @@ namespace backend {
cmd->~SetPushConstantsCmd(); cmd->~SetPushConstantsCmd();
} }
break; break;
case Command::SetStencilReference: case Command::SetStencilReference:
{ {
SetStencilReferenceCmd* cmd = commands->NextCommand<SetStencilReferenceCmd>(); SetStencilReferenceCmd* cmd = commands->NextCommand<SetStencilReferenceCmd>();
cmd->~SetStencilReferenceCmd(); cmd->~SetStencilReferenceCmd();
} }
break; break;
case Command::SetBindGroup: case Command::SetBindGroup:
{ {
SetBindGroupCmd* cmd = commands->NextCommand<SetBindGroupCmd>(); SetBindGroupCmd* cmd = commands->NextCommand<SetBindGroupCmd>();
@ -569,11 +569,11 @@ namespace backend {
} }
} }
break; break;
case Command::SetStencilReference: case Command::SetStencilReference:
{ {
SetStencilReferenceCmd* cmd = iterator.NextCommand<SetStencilReferenceCmd>(); SetStencilReferenceCmd* cmd = iterator.NextCommand<SetStencilReferenceCmd>();
} }
break; break;
case Command::SetBindGroup: case Command::SetBindGroup:

View File

@ -1,118 +1,118 @@
// Copyright 2017 The NXT Authors // Copyright 2017 The NXT Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "DepthStencilState.h" #include "DepthStencilState.h"
#include "Device.h" #include "Device.h"
namespace backend { namespace backend {
// DepthStencilStateBase // DepthStencilStateBase
DepthStencilStateBase::DepthStencilStateBase(DepthStencilStateBuilder* builder) DepthStencilStateBase::DepthStencilStateBase(DepthStencilStateBuilder* builder)
: depthEnabled(builder->depthEnabled), stencilEnabled(builder->stencilEnabled), : depthEnabled(builder->depthEnabled), stencilEnabled(builder->stencilEnabled),
depthInfo(builder->depthInfo), depthInfo(builder->depthInfo),
stencilInfos { builder->stencilInfos[0], builder->stencilInfos[1] } { stencilInfos { builder->stencilInfos[0], builder->stencilInfos[1] } {
} }
bool DepthStencilStateBase::DepthIsEnabled() const { bool DepthStencilStateBase::DepthIsEnabled() const {
return depthEnabled; return depthEnabled;
} }
bool DepthStencilStateBase::StencilIsEnabled() const { bool DepthStencilStateBase::StencilIsEnabled() const {
return stencilEnabled; return stencilEnabled;
} }
const DepthStencilStateBase::DepthInfo& DepthStencilStateBase::GetDepth() const { const DepthStencilStateBase::DepthInfo& DepthStencilStateBase::GetDepth() const {
return depthInfo; return depthInfo;
} }
const DepthStencilStateBase::StencilInfo& DepthStencilStateBase::GetStencil(nxt::Face face) const { const DepthStencilStateBase::StencilInfo& DepthStencilStateBase::GetStencil(nxt::Face face) const {
switch (face) { switch (face) {
case nxt::Face::Back: case nxt::Face::Back:
return stencilInfos[0]; return stencilInfos[0];
case nxt::Face::Front: case nxt::Face::Front:
return stencilInfos[1]; return stencilInfos[1];
default: default:
ASSERT(false); ASSERT(false);
} }
} }
// DepthStencilStateBuilder // DepthStencilStateBuilder
DepthStencilStateBuilder::DepthStencilStateBuilder(DeviceBase* device) : Builder(device) { DepthStencilStateBuilder::DepthStencilStateBuilder(DeviceBase* device) : Builder(device) {
} }
DepthStencilStateBase* DepthStencilStateBuilder::GetResultImpl() { DepthStencilStateBase* DepthStencilStateBuilder::GetResultImpl() {
return device->CreateDepthStencilState(this); return device->CreateDepthStencilState(this);
} }
void DepthStencilStateBuilder::SetDepthEnabled(bool depthEnabled) { void DepthStencilStateBuilder::SetDepthEnabled(bool depthEnabled) {
this->depthEnabled = depthEnabled; this->depthEnabled = depthEnabled;
} }
void DepthStencilStateBuilder::SetDepthCompareFunction(nxt::CompareFunction depthCompareFunction) { void DepthStencilStateBuilder::SetDepthCompareFunction(nxt::CompareFunction depthCompareFunction) {
depthInfo.compareFunction = depthCompareFunction; depthInfo.compareFunction = depthCompareFunction;
} }
void DepthStencilStateBuilder::SetDepthWrite(nxt::DepthWriteMode depthWriteMode) { void DepthStencilStateBuilder::SetDepthWrite(nxt::DepthWriteMode depthWriteMode) {
depthInfo.depthWriteMode = depthWriteMode; depthInfo.depthWriteMode = depthWriteMode;
} }
void DepthStencilStateBuilder::SetStencilEnabled(bool stencilEnabled) { void DepthStencilStateBuilder::SetStencilEnabled(bool stencilEnabled) {
this->stencilEnabled = stencilEnabled; this->stencilEnabled = stencilEnabled;
} }
void DepthStencilStateBuilder::SetStencilOperation(nxt::Face face, nxt::StencilOperation stencilFail, void DepthStencilStateBuilder::SetStencilOperation(nxt::Face face, nxt::StencilOperation stencilFail,
nxt::StencilOperation depthFail, nxt::StencilOperation stencilPass) { nxt::StencilOperation depthFail, nxt::StencilOperation stencilPass) {
if (face & nxt::Face::Back) { if (face & nxt::Face::Back) {
auto& stencilInfo = stencilInfos[0]; auto& stencilInfo = stencilInfos[0];
stencilInfo.stencilFail = stencilFail; stencilInfo.stencilFail = stencilFail;
stencilInfo.depthFail = stencilFail; stencilInfo.depthFail = stencilFail;
stencilInfo.stencilPass = stencilPass; stencilInfo.stencilPass = stencilPass;
} }
if (face & nxt::Face::Front) { if (face & nxt::Face::Front) {
auto& stencilInfo = stencilInfos[1]; auto& stencilInfo = stencilInfos[1];
stencilInfo.stencilFail = stencilFail; stencilInfo.stencilFail = stencilFail;
stencilInfo.depthFail = stencilFail; stencilInfo.depthFail = stencilFail;
stencilInfo.stencilPass = stencilPass; stencilInfo.stencilPass = stencilPass;
} }
} }
void DepthStencilStateBuilder::SetStencilCompareFunction(nxt::Face face, nxt::CompareFunction stencilCompareFunction) { void DepthStencilStateBuilder::SetStencilCompareFunction(nxt::Face face, nxt::CompareFunction stencilCompareFunction) {
if (face & nxt::Face::Back) { if (face & nxt::Face::Back) {
auto& stencilInfo = stencilInfos[0]; auto& stencilInfo = stencilInfos[0];
stencilInfo.compareFunction = stencilCompareFunction; stencilInfo.compareFunction = stencilCompareFunction;
} }
if (face & nxt::Face::Front) { if (face & nxt::Face::Front) {
auto& stencilInfo = stencilInfos[1]; auto& stencilInfo = stencilInfos[1];
stencilInfo.compareFunction = stencilCompareFunction; stencilInfo.compareFunction = stencilCompareFunction;
} }
} }
void DepthStencilStateBuilder::SetStencilMask(nxt::Face face, uint32_t readMask, uint32_t writeMask) { void DepthStencilStateBuilder::SetStencilMask(nxt::Face face, uint32_t readMask, uint32_t writeMask) {
if (face & nxt::Face::Back) { if (face & nxt::Face::Back) {
auto& stencilInfo = stencilInfos[0]; auto& stencilInfo = stencilInfos[0];
stencilInfo.readMask = readMask; stencilInfo.readMask = readMask;
stencilInfo.writeMask = writeMask; stencilInfo.writeMask = writeMask;
} }
if (face & nxt::Face::Front) { if (face & nxt::Face::Front) {
auto& stencilInfo = stencilInfos[1]; auto& stencilInfo = stencilInfos[1];
stencilInfo.readMask = readMask; stencilInfo.readMask = readMask;
stencilInfo.writeMask = writeMask; stencilInfo.writeMask = writeMask;
} }
} }
} }

View File

@ -1,84 +1,84 @@
// Copyright 2017 The NXT Authors // Copyright 2017 The NXT Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef BACKEND_COMMON_DEPTHSTENCILSTATE_H_ #ifndef BACKEND_COMMON_DEPTHSTENCILSTATE_H_
#define BACKEND_COMMON_DEPTHSTENCILSTATE_H_ #define BACKEND_COMMON_DEPTHSTENCILSTATE_H_
#include "Forward.h" #include "Forward.h"
#include "Builder.h" #include "Builder.h"
#include "RefCounted.h" #include "RefCounted.h"
#include "nxt/nxtcpp.h" #include "nxt/nxtcpp.h"
namespace backend { namespace backend {
class DepthStencilStateBase : public RefCounted { class DepthStencilStateBase : public RefCounted {
public: public:
DepthStencilStateBase(DepthStencilStateBuilder* builder); DepthStencilStateBase(DepthStencilStateBuilder* builder);
struct DepthInfo { struct DepthInfo {
nxt::CompareFunction compareFunction = nxt::CompareFunction::Less; nxt::CompareFunction compareFunction = nxt::CompareFunction::Less;
nxt::DepthWriteMode depthWriteMode = nxt::DepthWriteMode::Enabled; nxt::DepthWriteMode depthWriteMode = nxt::DepthWriteMode::Enabled;
}; };
struct StencilInfo { struct StencilInfo {
nxt::CompareFunction compareFunction = nxt::CompareFunction::Always; nxt::CompareFunction compareFunction = nxt::CompareFunction::Always;
nxt::StencilOperation stencilFail = nxt::StencilOperation::Keep; nxt::StencilOperation stencilFail = nxt::StencilOperation::Keep;
nxt::StencilOperation depthFail = nxt::StencilOperation::Keep; nxt::StencilOperation depthFail = nxt::StencilOperation::Keep;
nxt::StencilOperation stencilPass = nxt::StencilOperation::Keep; nxt::StencilOperation stencilPass = nxt::StencilOperation::Keep;
uint32_t readMask = 0xff; uint32_t readMask = 0xff;
uint32_t writeMask = 0xff; uint32_t writeMask = 0xff;
}; };
bool DepthIsEnabled() const; bool DepthIsEnabled() const;
bool StencilIsEnabled() const; bool StencilIsEnabled() const;
const DepthInfo& GetDepth() const; const DepthInfo& GetDepth() const;
const StencilInfo& GetStencil(nxt::Face face) const; const StencilInfo& GetStencil(nxt::Face face) const;
private: private:
bool depthEnabled = false; bool depthEnabled = false;
bool stencilEnabled = false; bool stencilEnabled = false;
DepthInfo depthInfo; DepthInfo depthInfo;
StencilInfo stencilInfos[2]; StencilInfo stencilInfos[2];
}; };
class DepthStencilStateBuilder : public Builder<DepthStencilStateBase> { class DepthStencilStateBuilder : public Builder<DepthStencilStateBase> {
public: public:
DepthStencilStateBuilder(DeviceBase* device); DepthStencilStateBuilder(DeviceBase* device);
// NXT API // NXT API
void SetDepthEnabled(bool depthEnabled); void SetDepthEnabled(bool depthEnabled);
void SetDepthCompareFunction(nxt::CompareFunction depthCompareFunction); void SetDepthCompareFunction(nxt::CompareFunction depthCompareFunction);
void SetDepthWrite(nxt::DepthWriteMode depthWriteMode); void SetDepthWrite(nxt::DepthWriteMode depthWriteMode);
void SetStencilEnabled(bool stencilEnabled); void SetStencilEnabled(bool stencilEnabled);
void SetStencilOperation(nxt::Face face, nxt::StencilOperation stencilFail, void SetStencilOperation(nxt::Face face, nxt::StencilOperation stencilFail,
nxt::StencilOperation depthFail, nxt::StencilOperation stencilPass); nxt::StencilOperation depthFail, nxt::StencilOperation stencilPass);
void SetStencilCompareFunction(nxt::Face face, nxt::CompareFunction stencilCompareFunction); void SetStencilCompareFunction(nxt::Face face, nxt::CompareFunction stencilCompareFunction);
void SetStencilMask(nxt::Face face, uint32_t readMask, uint32_t writeMask); void SetStencilMask(nxt::Face face, uint32_t readMask, uint32_t writeMask);
private: private:
friend class DepthStencilStateBase; friend class DepthStencilStateBase;
DepthStencilStateBase* GetResultImpl() override; DepthStencilStateBase* GetResultImpl() override;
bool depthEnabled; bool depthEnabled;
bool stencilEnabled; bool stencilEnabled;
DepthStencilStateBase::DepthInfo depthInfo; DepthStencilStateBase::DepthInfo depthInfo;
DepthStencilStateBase::StencilInfo stencilInfos[2]; DepthStencilStateBase::StencilInfo stencilInfos[2];
}; };
} }
#endif // BACKEND_COMMON_DEPTHSTENCILSTATE_H_ #endif // BACKEND_COMMON_DEPTHSTENCILSTATE_H_

View File

@ -1,137 +1,137 @@
// Copyright 2017 The NXT Authors // Copyright 2017 The NXT Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "Device.h" #include "Device.h"
#include "BindGroup.h" #include "BindGroup.h"
#include "BindGroupLayout.h" #include "BindGroupLayout.h"
#include "Buffer.h" #include "Buffer.h"
#include "CommandBuffer.h" #include "CommandBuffer.h"
#include "DepthStencilState.h" #include "DepthStencilState.h"
#include "Framebuffer.h" #include "Framebuffer.h"
#include "InputState.h" #include "InputState.h"
#include "Pipeline.h" #include "Pipeline.h"
#include "PipelineLayout.h" #include "PipelineLayout.h"
#include "Queue.h" #include "Queue.h"
#include "RenderPass.h" #include "RenderPass.h"
#include "Sampler.h" #include "Sampler.h"
#include "ShaderModule.h" #include "ShaderModule.h"
#include "Texture.h" #include "Texture.h"
#include <unordered_set> #include <unordered_set>
namespace backend { namespace backend {
// DeviceBase::Caches // DeviceBase::Caches
// The caches are unordered_sets of pointers with special hash and compare functions // The caches are unordered_sets of pointers with special hash and compare functions
// to compare the value of the objects, instead of the pointers. // to compare the value of the objects, instead of the pointers.
using BindGroupLayoutCache = std::unordered_set<BindGroupLayoutBase*, BindGroupLayoutCacheFuncs, BindGroupLayoutCacheFuncs>; using BindGroupLayoutCache = std::unordered_set<BindGroupLayoutBase*, BindGroupLayoutCacheFuncs, BindGroupLayoutCacheFuncs>;
struct DeviceBase::Caches { struct DeviceBase::Caches {
BindGroupLayoutCache bindGroupLayouts; BindGroupLayoutCache bindGroupLayouts;
}; };
// DeviceBase // DeviceBase
DeviceBase::DeviceBase() { DeviceBase::DeviceBase() {
caches = new DeviceBase::Caches(); caches = new DeviceBase::Caches();
} }
DeviceBase::~DeviceBase() { DeviceBase::~DeviceBase() {
delete caches; delete caches;
} }
void DeviceBase::HandleError(const char* message) { void DeviceBase::HandleError(const char* message) {
if (errorCallback) { if (errorCallback) {
errorCallback(message, errorUserdata); errorCallback(message, errorUserdata);
} }
} }
void DeviceBase::SetErrorCallback(nxt::DeviceErrorCallback callback, nxt::CallbackUserdata userdata) { void DeviceBase::SetErrorCallback(nxt::DeviceErrorCallback callback, nxt::CallbackUserdata userdata) {
this->errorCallback = callback; this->errorCallback = callback;
this->errorUserdata = userdata; this->errorUserdata = userdata;
} }
DeviceBase* DeviceBase::GetDevice() { DeviceBase* DeviceBase::GetDevice() {
return this; return this;
} }
BindGroupLayoutBase* DeviceBase::GetOrCreateBindGroupLayout(const BindGroupLayoutBase* blueprint, BindGroupLayoutBuilder* builder) { BindGroupLayoutBase* DeviceBase::GetOrCreateBindGroupLayout(const BindGroupLayoutBase* blueprint, BindGroupLayoutBuilder* builder) {
// The blueprint is only used to search in the cache and is not modified. However cached // The blueprint is only used to search in the cache and is not modified. However cached
// objects can be modified, and unordered_set cannot search for a const pointer in a non // objects can be modified, and unordered_set cannot search for a const pointer in a non
// const pointer set. That's why we do a const_cast here, but the blueprint won't be // const pointer set. That's why we do a const_cast here, but the blueprint won't be
// modified. // modified.
auto iter = caches->bindGroupLayouts.find(const_cast<BindGroupLayoutBase*>(blueprint)); auto iter = caches->bindGroupLayouts.find(const_cast<BindGroupLayoutBase*>(blueprint));
if (iter != caches->bindGroupLayouts.end()) { if (iter != caches->bindGroupLayouts.end()) {
return *iter; return *iter;
} }
BindGroupLayoutBase* backendObj = CreateBindGroupLayout(builder); BindGroupLayoutBase* backendObj = CreateBindGroupLayout(builder);
caches->bindGroupLayouts.insert(backendObj); caches->bindGroupLayouts.insert(backendObj);
return backendObj; return backendObj;
} }
void DeviceBase::UncacheBindGroupLayout(BindGroupLayoutBase* obj) { void DeviceBase::UncacheBindGroupLayout(BindGroupLayoutBase* obj) {
caches->bindGroupLayouts.erase(obj); caches->bindGroupLayouts.erase(obj);
} }
BindGroupBuilder* DeviceBase::CreateBindGroupBuilder() { BindGroupBuilder* DeviceBase::CreateBindGroupBuilder() {
return new BindGroupBuilder(this); return new BindGroupBuilder(this);
} }
BindGroupLayoutBuilder* DeviceBase::CreateBindGroupLayoutBuilder() { BindGroupLayoutBuilder* DeviceBase::CreateBindGroupLayoutBuilder() {
return new BindGroupLayoutBuilder(this); return new BindGroupLayoutBuilder(this);
} }
BufferBuilder* DeviceBase::CreateBufferBuilder() { BufferBuilder* DeviceBase::CreateBufferBuilder() {
return new BufferBuilder(this); return new BufferBuilder(this);
} }
CommandBufferBuilder* DeviceBase::CreateCommandBufferBuilder() { CommandBufferBuilder* DeviceBase::CreateCommandBufferBuilder() {
return new CommandBufferBuilder(this); return new CommandBufferBuilder(this);
} }
DepthStencilStateBuilder* DeviceBase::CreateDepthStencilStateBuilder() { DepthStencilStateBuilder* DeviceBase::CreateDepthStencilStateBuilder() {
return new DepthStencilStateBuilder(this); return new DepthStencilStateBuilder(this);
} }
FramebufferBuilder* DeviceBase::CreateFramebufferBuilder() { FramebufferBuilder* DeviceBase::CreateFramebufferBuilder() {
return new FramebufferBuilder(this); return new FramebufferBuilder(this);
} }
InputStateBuilder* DeviceBase::CreateInputStateBuilder() { InputStateBuilder* DeviceBase::CreateInputStateBuilder() {
return new InputStateBuilder(this); return new InputStateBuilder(this);
} }
PipelineBuilder* DeviceBase::CreatePipelineBuilder() { PipelineBuilder* DeviceBase::CreatePipelineBuilder() {
return new PipelineBuilder(this); return new PipelineBuilder(this);
} }
PipelineLayoutBuilder* DeviceBase::CreatePipelineLayoutBuilder() { PipelineLayoutBuilder* DeviceBase::CreatePipelineLayoutBuilder() {
return new PipelineLayoutBuilder(this); return new PipelineLayoutBuilder(this);
} }
QueueBuilder* DeviceBase::CreateQueueBuilder() { QueueBuilder* DeviceBase::CreateQueueBuilder() {
return new QueueBuilder(this); return new QueueBuilder(this);
} }
RenderPassBuilder* DeviceBase::CreateRenderPassBuilder() { RenderPassBuilder* DeviceBase::CreateRenderPassBuilder() {
return new RenderPassBuilder(this); return new RenderPassBuilder(this);
} }
SamplerBuilder* DeviceBase::CreateSamplerBuilder() { SamplerBuilder* DeviceBase::CreateSamplerBuilder() {
return new SamplerBuilder(this); return new SamplerBuilder(this);
} }
ShaderModuleBuilder* DeviceBase::CreateShaderModuleBuilder() { ShaderModuleBuilder* DeviceBase::CreateShaderModuleBuilder() {
return new ShaderModuleBuilder(this); return new ShaderModuleBuilder(this);
} }
TextureBuilder* DeviceBase::CreateTextureBuilder() { TextureBuilder* DeviceBase::CreateTextureBuilder() {
return new TextureBuilder(this); return new TextureBuilder(this);
} }
void DeviceBase::CopyBindGroups(uint32_t start, uint32_t count, BindGroupBase* source, BindGroupBase* target) { void DeviceBase::CopyBindGroups(uint32_t start, uint32_t count, BindGroupBase* source, BindGroupBase* target) {
// TODO(cwallez@chromium.org): update state tracking then call the backend // TODO(cwallez@chromium.org): update state tracking then call the backend
} }
} }

View File

@ -1,103 +1,103 @@
// Copyright 2017 The NXT Authors // Copyright 2017 The NXT Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef BACKEND_COMMON_DEVICEBASE_H_ #ifndef BACKEND_COMMON_DEVICEBASE_H_
#define BACKEND_COMMON_DEVICEBASE_H_ #define BACKEND_COMMON_DEVICEBASE_H_
#include "common/Forward.h" #include "common/Forward.h"
#include "common/RefCounted.h" #include "common/RefCounted.h"
#include "nxt/nxtcpp.h" #include "nxt/nxtcpp.h"
namespace backend { namespace backend {
using ErrorCallback = void (*)(const char* errorMessage, void* userData); using ErrorCallback = void (*)(const char* errorMessage, void* userData);
class DeviceBase { class DeviceBase {
public: public:
DeviceBase(); DeviceBase();
~DeviceBase(); ~DeviceBase();
void HandleError(const char* message); void HandleError(const char* message);
void SetErrorCallback(nxt::DeviceErrorCallback callback, nxt::CallbackUserdata userdata); void SetErrorCallback(nxt::DeviceErrorCallback callback, nxt::CallbackUserdata userdata);
// Used by autogenerated code, returns itself // Used by autogenerated code, returns itself
DeviceBase* GetDevice(); DeviceBase* GetDevice();
virtual BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) = 0; virtual BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) = 0;
virtual BindGroupLayoutBase* CreateBindGroupLayout(BindGroupLayoutBuilder* builder) = 0; virtual BindGroupLayoutBase* CreateBindGroupLayout(BindGroupLayoutBuilder* builder) = 0;
virtual BufferBase* CreateBuffer(BufferBuilder* builder) = 0; virtual BufferBase* CreateBuffer(BufferBuilder* builder) = 0;
virtual BufferViewBase* CreateBufferView(BufferViewBuilder* builder) = 0; virtual BufferViewBase* CreateBufferView(BufferViewBuilder* builder) = 0;
virtual CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) = 0; virtual CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) = 0;
virtual DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) = 0; virtual DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) = 0;
virtual FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) = 0; virtual FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) = 0;
virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0; virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0;
virtual PipelineBase* CreatePipeline(PipelineBuilder* builder) = 0; virtual PipelineBase* CreatePipeline(PipelineBuilder* builder) = 0;
virtual PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) = 0; virtual PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) = 0;
virtual QueueBase* CreateQueue(QueueBuilder* builder) = 0; virtual QueueBase* CreateQueue(QueueBuilder* builder) = 0;
virtual RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) = 0; virtual RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) = 0;
virtual SamplerBase* CreateSampler(SamplerBuilder* builder) = 0; virtual SamplerBase* CreateSampler(SamplerBuilder* builder) = 0;
virtual ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) = 0; virtual ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) = 0;
virtual TextureBase* CreateTexture(TextureBuilder* builder) = 0; virtual TextureBase* CreateTexture(TextureBuilder* builder) = 0;
virtual TextureViewBase* CreateTextureView(TextureViewBuilder* builder) = 0; virtual TextureViewBase* CreateTextureView(TextureViewBuilder* builder) = 0;
// Many NXT objects are completely immutable once created which means that if two // Many NXT objects are completely immutable once created which means that if two
// builders are given the same arguments, they can return the same object. Reusing // builders are given the same arguments, they can return the same object. Reusing
// objects will help make comparisons between objects by a single pointer comparison. // objects will help make comparisons between objects by a single pointer comparison.
// //
// Technically no object is immutable as they have a reference count, and an // Technically no object is immutable as they have a reference count, and an
// application with reference-counting issues could "see" that objects are reused. // application with reference-counting issues could "see" that objects are reused.
// This is solved by automatic-reference counting, and also the fact that when using // This is solved by automatic-reference counting, and also the fact that when using
// the client-server wire every creation will get a different proxy object, with a // the client-server wire every creation will get a different proxy object, with a
// different reference count. // different reference count.
// //
// When trying to create an object, we give both the builder and an example of what // When trying to create an object, we give both the builder and an example of what
// the built object will be, the "blueprint". The blueprint is just a FooBase object // the built object will be, the "blueprint". The blueprint is just a FooBase object
// instead of a backend Foo object. If the blueprint doesn't match an object in the // instead of a backend Foo object. If the blueprint doesn't match an object in the
// cache, then the builder is used to make a new object. // cache, then the builder is used to make a new object.
BindGroupLayoutBase* GetOrCreateBindGroupLayout(const BindGroupLayoutBase* blueprint, BindGroupLayoutBuilder* builder); BindGroupLayoutBase* GetOrCreateBindGroupLayout(const BindGroupLayoutBase* blueprint, BindGroupLayoutBuilder* builder);
void UncacheBindGroupLayout(BindGroupLayoutBase* obj); void UncacheBindGroupLayout(BindGroupLayoutBase* obj);
// NXT API // NXT API
BindGroupBuilder* CreateBindGroupBuilder(); BindGroupBuilder* CreateBindGroupBuilder();
BindGroupLayoutBuilder* CreateBindGroupLayoutBuilder(); BindGroupLayoutBuilder* CreateBindGroupLayoutBuilder();
BufferBuilder* CreateBufferBuilder(); BufferBuilder* CreateBufferBuilder();
BufferViewBuilder* CreateBufferViewBuilder(); BufferViewBuilder* CreateBufferViewBuilder();
CommandBufferBuilder* CreateCommandBufferBuilder(); CommandBufferBuilder* CreateCommandBufferBuilder();
DepthStencilStateBuilder* CreateDepthStencilStateBuilder(); DepthStencilStateBuilder* CreateDepthStencilStateBuilder();
FramebufferBuilder* CreateFramebufferBuilder(); FramebufferBuilder* CreateFramebufferBuilder();
InputStateBuilder* CreateInputStateBuilder(); InputStateBuilder* CreateInputStateBuilder();
PipelineBuilder* CreatePipelineBuilder(); PipelineBuilder* CreatePipelineBuilder();
PipelineLayoutBuilder* CreatePipelineLayoutBuilder(); PipelineLayoutBuilder* CreatePipelineLayoutBuilder();
QueueBuilder* CreateQueueBuilder(); QueueBuilder* CreateQueueBuilder();
RenderPassBuilder* CreateRenderPassBuilder(); RenderPassBuilder* CreateRenderPassBuilder();
SamplerBuilder* CreateSamplerBuilder(); SamplerBuilder* CreateSamplerBuilder();
ShaderModuleBuilder* CreateShaderModuleBuilder(); ShaderModuleBuilder* CreateShaderModuleBuilder();
TextureBuilder* CreateTextureBuilder(); TextureBuilder* CreateTextureBuilder();
void CopyBindGroups(uint32_t start, uint32_t count, BindGroupBase* source, BindGroupBase* target); void CopyBindGroups(uint32_t start, uint32_t count, BindGroupBase* source, BindGroupBase* target);
private: private:
// The object caches aren't exposed in the header as they would require a lot of // The object caches aren't exposed in the header as they would require a lot of
// additional includes. // additional includes.
struct Caches; struct Caches;
Caches* caches = nullptr; Caches* caches = nullptr;
nxt::DeviceErrorCallback errorCallback = nullptr; nxt::DeviceErrorCallback errorCallback = nullptr;
nxt::CallbackUserdata errorUserdata = 0; nxt::CallbackUserdata errorUserdata = 0;
}; };
} }
#endif // BACKEND_COMMON_DEVICEBASE_H_ #endif // BACKEND_COMMON_DEVICEBASE_H_

View File

@ -1,78 +1,78 @@
// Copyright 2017 The NXT Authors // Copyright 2017 The NXT Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef BACKEND_COMMON_FORWARD_H_ #ifndef BACKEND_COMMON_FORWARD_H_
#define BACKEND_COMMON_FORWARD_H_ #define BACKEND_COMMON_FORWARD_H_
#include <cassert> #include <cassert>
#include <cstdint> #include <cstdint>
#define ASSERT assert #define ASSERT assert
namespace backend { namespace backend {
class BindGroupBase; class BindGroupBase;
class BindGroupBuilder; class BindGroupBuilder;
class BindGroupLayoutBase; class BindGroupLayoutBase;
class BindGroupLayoutBuilder; class BindGroupLayoutBuilder;
class BufferBase; class BufferBase;
class BufferBuilder; class BufferBuilder;
class BufferViewBase; class BufferViewBase;
class BufferViewBuilder; class BufferViewBuilder;
class CommandBufferBase; class CommandBufferBase;
class CommandBufferBuilder; class CommandBufferBuilder;
class DepthStencilStateBase; class DepthStencilStateBase;
class DepthStencilStateBuilder; class DepthStencilStateBuilder;
class FramebufferBase; class FramebufferBase;
class FramebufferBuilder; class FramebufferBuilder;
class InputStateBase; class InputStateBase;
class InputStateBuilder; class InputStateBuilder;
class PipelineBase; class PipelineBase;
class PipelineBuilder; class PipelineBuilder;
class PipelineLayoutBase; class PipelineLayoutBase;
class PipelineLayoutBuilder; class PipelineLayoutBuilder;
class QueueBase; class QueueBase;
class QueueBuilder; class QueueBuilder;
class RenderPassBase; class RenderPassBase;
class RenderPassBuilder; class RenderPassBuilder;
class SamplerBase; class SamplerBase;
class SamplerBuilder; class SamplerBuilder;
class ShaderModuleBase; class ShaderModuleBase;
class ShaderModuleBuilder; class ShaderModuleBuilder;
class TextureBase; class TextureBase;
class TextureBuilder; class TextureBuilder;
class TextureViewBase; class TextureViewBase;
class TextureViewBuilder; class TextureViewBuilder;
class DeviceBase; class DeviceBase;
template<typename T> template<typename T>
class Ref; class Ref;
template<typename T> template<typename T>
class PerStage; class PerStage;
// TODO(cwallez@chromium.org): where should constants live? // TODO(cwallez@chromium.org): where should constants live?
static constexpr uint32_t kMaxPushConstants = 32u; static constexpr uint32_t kMaxPushConstants = 32u;
static constexpr uint32_t kMaxBindGroups = 4u; static constexpr uint32_t kMaxBindGroups = 4u;
static constexpr uint32_t kMaxBindingsPerGroup = 16u; // TODO(cwallez@chromium.org): investigate bindgroup limits static constexpr uint32_t kMaxBindingsPerGroup = 16u; // TODO(cwallez@chromium.org): investigate bindgroup limits
static constexpr uint32_t kMaxVertexAttributes = 16u; static constexpr uint32_t kMaxVertexAttributes = 16u;
static constexpr uint32_t kMaxVertexInputs = 16u; static constexpr uint32_t kMaxVertexInputs = 16u;
static constexpr uint32_t kNumStages = 3; static constexpr uint32_t kNumStages = 3;
static constexpr uint32_t kMaxColorAttachments = 4u; static constexpr uint32_t kMaxColorAttachments = 4u;
enum PushConstantType : uint8_t; enum PushConstantType : uint8_t;
} }
#endif // BACKEND_COMMON_FORWARD_H_ #endif // BACKEND_COMMON_FORWARD_H_

View File

@ -1,173 +1,173 @@
// Copyright 2017 The NXT Authors // Copyright 2017 The NXT Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "Pipeline.h" #include "Pipeline.h"
#include "Device.h" #include "Device.h"
#include "DepthStencilState.h" #include "DepthStencilState.h"
#include "InputState.h" #include "InputState.h"
#include "PipelineLayout.h" #include "PipelineLayout.h"
#include "RenderPass.h" #include "RenderPass.h"
#include "ShaderModule.h" #include "ShaderModule.h"
namespace backend { namespace backend {
// PipelineBase // PipelineBase
PipelineBase::PipelineBase(PipelineBuilder* builder) PipelineBase::PipelineBase(PipelineBuilder* builder)
: device(builder->device), stageMask(builder->stageMask), layout(std::move(builder->layout)), : device(builder->device), stageMask(builder->stageMask), layout(std::move(builder->layout)),
renderPass(std::move(builder->renderPass)), subpass(builder->subpass), renderPass(std::move(builder->renderPass)), subpass(builder->subpass),
inputState(std::move(builder->inputState)), depthStencilState(std::move(builder->depthStencilState)) { inputState(std::move(builder->inputState)), depthStencilState(std::move(builder->depthStencilState)) {
if (stageMask != (nxt::ShaderStageBit::Vertex | nxt::ShaderStageBit::Fragment) && if (stageMask != (nxt::ShaderStageBit::Vertex | nxt::ShaderStageBit::Fragment) &&
stageMask != nxt::ShaderStageBit::Compute) { stageMask != nxt::ShaderStageBit::Compute) {
builder->HandleError("Wrong combination of stage for pipeline"); builder->HandleError("Wrong combination of stage for pipeline");
return; return;
} }
if (!IsCompute() && !renderPass) { if (!IsCompute() && !renderPass) {
builder->HandleError("Pipeline render pass not set"); builder->HandleError("Pipeline render pass not set");
return; return;
} }
// TODO(kainino@chromium.org): Need to verify the pipeline against its render subpass. // TODO(kainino@chromium.org): Need to verify the pipeline against its render subpass.
auto FillPushConstants = [](const ShaderModuleBase* module, PushConstantInfo* info) { auto FillPushConstants = [](const ShaderModuleBase* module, PushConstantInfo* info) {
const auto& moduleInfo = module->GetPushConstants(); const auto& moduleInfo = module->GetPushConstants();
info->mask = moduleInfo.mask; info->mask = moduleInfo.mask;
for (uint32_t i = 0; i < moduleInfo.names.size(); i++) { for (uint32_t i = 0; i < moduleInfo.names.size(); i++) {
unsigned int size = moduleInfo.sizes[i]; unsigned int size = moduleInfo.sizes[i];
if (size == 0) { if (size == 0) {
continue; continue;
} }
for (uint32_t offset = 0; offset < size; offset++) { for (uint32_t offset = 0; offset < size; offset++) {
info->types[i + offset] = moduleInfo.types[i]; info->types[i + offset] = moduleInfo.types[i];
} }
i += size - 1; i += size - 1;
} }
}; };
for (auto stageBit : IterateStages(builder->stageMask)) { for (auto stageBit : IterateStages(builder->stageMask)) {
if (!builder->stages[stageBit].module->IsCompatibleWithPipelineLayout(layout.Get())) { if (!builder->stages[stageBit].module->IsCompatibleWithPipelineLayout(layout.Get())) {
builder->HandleError("Stage not compatible with layout"); builder->HandleError("Stage not compatible with layout");
return; return;
} }
FillPushConstants(builder->stages[stageBit].module.Get(), &pushConstants[stageBit]); FillPushConstants(builder->stages[stageBit].module.Get(), &pushConstants[stageBit]);
} }
if (!IsCompute()) { if (!IsCompute()) {
if ((builder->stages[nxt::ShaderStage::Vertex].module->GetUsedVertexAttributes() & ~inputState->GetAttributesSetMask()).any()) { if ((builder->stages[nxt::ShaderStage::Vertex].module->GetUsedVertexAttributes() & ~inputState->GetAttributesSetMask()).any()) {
builder->HandleError("Pipeline vertex stage uses inputs not in the input state"); builder->HandleError("Pipeline vertex stage uses inputs not in the input state");
return; return;
} }
} }
} }
const PipelineBase::PushConstantInfo& PipelineBase::GetPushConstants(nxt::ShaderStage stage) const { const PipelineBase::PushConstantInfo& PipelineBase::GetPushConstants(nxt::ShaderStage stage) const {
return pushConstants[stage]; return pushConstants[stage];
} }
nxt::ShaderStageBit PipelineBase::GetStageMask() const { nxt::ShaderStageBit PipelineBase::GetStageMask() const {
return stageMask; return stageMask;
} }
PipelineLayoutBase* PipelineBase::GetLayout() { PipelineLayoutBase* PipelineBase::GetLayout() {
return layout.Get(); return layout.Get();
} }
RenderPassBase* PipelineBase::GetRenderPass() { RenderPassBase* PipelineBase::GetRenderPass() {
return renderPass.Get(); return renderPass.Get();
} }
InputStateBase* PipelineBase::GetInputState() { InputStateBase* PipelineBase::GetInputState() {
return inputState.Get(); return inputState.Get();
} }
DepthStencilStateBase* PipelineBase::GetDepthStencilState() { DepthStencilStateBase* PipelineBase::GetDepthStencilState() {
return depthStencilState.Get(); return depthStencilState.Get();
} }
bool PipelineBase::IsCompute() const { bool PipelineBase::IsCompute() const {
return stageMask == nxt::ShaderStageBit::Compute; return stageMask == nxt::ShaderStageBit::Compute;
} }
// PipelineBuilder // PipelineBuilder
PipelineBuilder::PipelineBuilder(DeviceBase* device) PipelineBuilder::PipelineBuilder(DeviceBase* device)
: Builder(device), stageMask(static_cast<nxt::ShaderStageBit>(0)) { : Builder(device), stageMask(static_cast<nxt::ShaderStageBit>(0)) {
} }
const PipelineBuilder::StageInfo& PipelineBuilder::GetStageInfo(nxt::ShaderStage stage) const { const PipelineBuilder::StageInfo& PipelineBuilder::GetStageInfo(nxt::ShaderStage stage) const {
ASSERT(stageMask & StageBit(stage)); ASSERT(stageMask & StageBit(stage));
return stages[stage]; return stages[stage];
} }
PipelineBase* PipelineBuilder::GetResultImpl() { PipelineBase* PipelineBuilder::GetResultImpl() {
// TODO(cwallez@chromium.org): the layout should be required, and put the default objects in the device // TODO(cwallez@chromium.org): the layout should be required, and put the default objects in the device
if (!layout) { if (!layout) {
layout = device->CreatePipelineLayoutBuilder()->GetResult(); layout = device->CreatePipelineLayoutBuilder()->GetResult();
} }
if (!inputState) { if (!inputState) {
inputState = device->CreateInputStateBuilder()->GetResult(); inputState = device->CreateInputStateBuilder()->GetResult();
} }
if (!depthStencilState) { if (!depthStencilState) {
depthStencilState = device->CreateDepthStencilStateBuilder()->GetResult(); depthStencilState = device->CreateDepthStencilStateBuilder()->GetResult();
} }
return device->CreatePipeline(this); return device->CreatePipeline(this);
} }
void PipelineBuilder::SetLayout(PipelineLayoutBase* layout) { void PipelineBuilder::SetLayout(PipelineLayoutBase* layout) {
this->layout = layout; this->layout = layout;
} }
void PipelineBuilder::SetSubpass(RenderPassBase* renderPass, uint32_t subpass) { void PipelineBuilder::SetSubpass(RenderPassBase* renderPass, uint32_t subpass) {
this->renderPass = renderPass; this->renderPass = renderPass;
this->subpass = subpass; this->subpass = subpass;
} }
void PipelineBuilder::SetStage(nxt::ShaderStage stage, ShaderModuleBase* module, const char* entryPoint) { void PipelineBuilder::SetStage(nxt::ShaderStage stage, ShaderModuleBase* module, const char* entryPoint) {
if (entryPoint != std::string("main")) { if (entryPoint != std::string("main")) {
HandleError("Currently the entry point has to be main()"); HandleError("Currently the entry point has to be main()");
return; return;
} }
if (stage != module->GetExecutionModel()) { if (stage != module->GetExecutionModel()) {
HandleError("Setting module with wrong execution model"); HandleError("Setting module with wrong execution model");
return; return;
} }
nxt::ShaderStageBit bit = StageBit(stage); nxt::ShaderStageBit bit = StageBit(stage);
if (stageMask & bit) { if (stageMask & bit) {
HandleError("Setting already set stage"); HandleError("Setting already set stage");
return; return;
} }
stageMask |= bit; stageMask |= bit;
stages[stage].module = module; stages[stage].module = module;
stages[stage].entryPoint = entryPoint; stages[stage].entryPoint = entryPoint;
} }
void PipelineBuilder::SetInputState(InputStateBase* inputState) { void PipelineBuilder::SetInputState(InputStateBase* inputState) {
this->inputState = inputState; this->inputState = inputState;
} }
void PipelineBuilder::SetDepthStencilState(DepthStencilStateBase* depthStencilState) { void PipelineBuilder::SetDepthStencilState(DepthStencilStateBase* depthStencilState) {
this->depthStencilState = depthStencilState; this->depthStencilState = depthStencilState;
} }
} }

View File

@ -1,100 +1,100 @@
// Copyright 2017 The NXT Authors // Copyright 2017 The NXT Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef BACKEND_COMMON_PIPELINE_H_ #ifndef BACKEND_COMMON_PIPELINE_H_
#define BACKEND_COMMON_PIPELINE_H_ #define BACKEND_COMMON_PIPELINE_H_
#include "Forward.h" #include "Forward.h"
#include "Builder.h" #include "Builder.h"
#include "PerStage.h" #include "PerStage.h"
#include "RefCounted.h" #include "RefCounted.h"
#include "nxt/nxtcpp.h" #include "nxt/nxtcpp.h"
#include <array> #include <array>
#include <bitset> #include <bitset>
namespace backend { namespace backend {
enum PushConstantType : uint8_t { enum PushConstantType : uint8_t {
Int, Int,
UInt, UInt,
Float, Float,
}; };
class PipelineBase : public RefCounted { class PipelineBase : public RefCounted {
public: public:
PipelineBase(PipelineBuilder* builder); PipelineBase(PipelineBuilder* builder);
struct PushConstantInfo { struct PushConstantInfo {
std::bitset<kMaxPushConstants> mask; std::bitset<kMaxPushConstants> mask;
std::array<PushConstantType, kMaxPushConstants> types; std::array<PushConstantType, kMaxPushConstants> types;
}; };
const PushConstantInfo& GetPushConstants(nxt::ShaderStage stage) const; const PushConstantInfo& GetPushConstants(nxt::ShaderStage stage) const;
nxt::ShaderStageBit GetStageMask() const; nxt::ShaderStageBit GetStageMask() const;
PipelineLayoutBase* GetLayout(); PipelineLayoutBase* GetLayout();
RenderPassBase* GetRenderPass(); RenderPassBase* GetRenderPass();
InputStateBase* GetInputState(); InputStateBase* GetInputState();
DepthStencilStateBase* GetDepthStencilState(); DepthStencilStateBase* GetDepthStencilState();
// TODO(cwallez@chromium.org): split compute and render pipelines // TODO(cwallez@chromium.org): split compute and render pipelines
bool IsCompute() const; bool IsCompute() const;
private: private:
DeviceBase* device; DeviceBase* device;
nxt::ShaderStageBit stageMask; nxt::ShaderStageBit stageMask;
Ref<PipelineLayoutBase> layout; Ref<PipelineLayoutBase> layout;
Ref<RenderPassBase> renderPass; Ref<RenderPassBase> renderPass;
uint32_t subpass; uint32_t subpass;
PerStage<PushConstantInfo> pushConstants; PerStage<PushConstantInfo> pushConstants;
Ref<InputStateBase> inputState; Ref<InputStateBase> inputState;
Ref<DepthStencilStateBase> depthStencilState; Ref<DepthStencilStateBase> depthStencilState;
}; };
class PipelineBuilder : public Builder<PipelineBase> { class PipelineBuilder : public Builder<PipelineBase> {
public: public:
PipelineBuilder(DeviceBase* device); PipelineBuilder(DeviceBase* device);
struct StageInfo { struct StageInfo {
std::string entryPoint; std::string entryPoint;
Ref<ShaderModuleBase> module; Ref<ShaderModuleBase> module;
}; };
const StageInfo& GetStageInfo(nxt::ShaderStage stage) const; const StageInfo& GetStageInfo(nxt::ShaderStage stage) const;
// NXT API // NXT API
void SetLayout(PipelineLayoutBase* layout); void SetLayout(PipelineLayoutBase* layout);
void SetSubpass(RenderPassBase* renderPass, uint32_t subpass); void SetSubpass(RenderPassBase* renderPass, uint32_t subpass);
void SetStage(nxt::ShaderStage stage, ShaderModuleBase* module, const char* entryPoint); void SetStage(nxt::ShaderStage stage, ShaderModuleBase* module, const char* entryPoint);
void SetInputState(InputStateBase* inputState); void SetInputState(InputStateBase* inputState);
void SetDepthStencilState(DepthStencilStateBase* depthStencilState); void SetDepthStencilState(DepthStencilStateBase* depthStencilState);
private: private:
friend class PipelineBase; friend class PipelineBase;
PipelineBase* GetResultImpl() override; PipelineBase* GetResultImpl() override;
Ref<PipelineLayoutBase> layout; Ref<PipelineLayoutBase> layout;
Ref<RenderPassBase> renderPass; Ref<RenderPassBase> renderPass;
uint32_t subpass; uint32_t subpass;
nxt::ShaderStageBit stageMask; nxt::ShaderStageBit stageMask;
PerStage<StageInfo> stages; PerStage<StageInfo> stages;
Ref<InputStateBase> inputState; Ref<InputStateBase> inputState;
Ref<DepthStencilStateBase> depthStencilState; Ref<DepthStencilStateBase> depthStencilState;
}; };
} }
#endif // BACKEND_COMMON_PIPELINE_H_ #endif // BACKEND_COMMON_PIPELINE_H_

View File

@ -1,135 +1,135 @@
// Copyright 2017 The NXT Authors // Copyright 2017 The NXT Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef BACKEND_COMMON_TOBACKEND_H_ #ifndef BACKEND_COMMON_TOBACKEND_H_
#define BACKEND_COMMON_TOBACKEND_H_ #define BACKEND_COMMON_TOBACKEND_H_
#include "Forward.h" #include "Forward.h"
namespace backend { namespace backend {
// ToBackendTraits implements the mapping from base type to member type of BackendTraits // ToBackendTraits implements the mapping from base type to member type of BackendTraits
template<typename T, typename BackendTraits> template<typename T, typename BackendTraits>
struct ToBackendTraits; struct ToBackendTraits;
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<BindGroupBase, BackendTraits> { struct ToBackendTraits<BindGroupBase, BackendTraits> {
using BackendType = typename BackendTraits::BindGroupType; using BackendType = typename BackendTraits::BindGroupType;
}; };
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<BindGroupLayoutBase, BackendTraits> { struct ToBackendTraits<BindGroupLayoutBase, BackendTraits> {
using BackendType = typename BackendTraits::BindGroupLayoutType; using BackendType = typename BackendTraits::BindGroupLayoutType;
}; };
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<BufferBase, BackendTraits> { struct ToBackendTraits<BufferBase, BackendTraits> {
using BackendType = typename BackendTraits::BufferType; using BackendType = typename BackendTraits::BufferType;
}; };
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<BufferViewBase, BackendTraits> { struct ToBackendTraits<BufferViewBase, BackendTraits> {
using BackendType = typename BackendTraits::BufferViewType; using BackendType = typename BackendTraits::BufferViewType;
}; };
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<CommandBufferBase, BackendTraits> { struct ToBackendTraits<CommandBufferBase, BackendTraits> {
using BackendType = typename BackendTraits::CommandBufferType; using BackendType = typename BackendTraits::CommandBufferType;
}; };
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<DepthStencilStateBase, BackendTraits> { struct ToBackendTraits<DepthStencilStateBase, BackendTraits> {
using BackendType = typename BackendTraits::DepthStencilStateType; using BackendType = typename BackendTraits::DepthStencilStateType;
}; };
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<FramebufferBase, BackendTraits> { struct ToBackendTraits<FramebufferBase, BackendTraits> {
using BackendType = typename BackendTraits::FramebufferType; using BackendType = typename BackendTraits::FramebufferType;
}; };
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<InputStateBase, BackendTraits> { struct ToBackendTraits<InputStateBase, BackendTraits> {
using BackendType = typename BackendTraits::InputStateType; using BackendType = typename BackendTraits::InputStateType;
}; };
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<PipelineBase, BackendTraits> { struct ToBackendTraits<PipelineBase, BackendTraits> {
using BackendType = typename BackendTraits::PipelineType; using BackendType = typename BackendTraits::PipelineType;
}; };
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<PipelineLayoutBase, BackendTraits> { struct ToBackendTraits<PipelineLayoutBase, BackendTraits> {
using BackendType = typename BackendTraits::PipelineLayoutType; using BackendType = typename BackendTraits::PipelineLayoutType;
}; };
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<QueueBase, BackendTraits> { struct ToBackendTraits<QueueBase, BackendTraits> {
using BackendType = typename BackendTraits::QueueType; using BackendType = typename BackendTraits::QueueType;
}; };
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<RenderPassBase, BackendTraits> { struct ToBackendTraits<RenderPassBase, BackendTraits> {
using BackendType = typename BackendTraits::RenderPassType; using BackendType = typename BackendTraits::RenderPassType;
}; };
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<SamplerBase, BackendTraits> { struct ToBackendTraits<SamplerBase, BackendTraits> {
using BackendType = typename BackendTraits::SamplerType; using BackendType = typename BackendTraits::SamplerType;
}; };
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<ShaderModuleBase, BackendTraits> { struct ToBackendTraits<ShaderModuleBase, BackendTraits> {
using BackendType = typename BackendTraits::ShaderModuleType; using BackendType = typename BackendTraits::ShaderModuleType;
}; };
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<TextureBase, BackendTraits> { struct ToBackendTraits<TextureBase, BackendTraits> {
using BackendType = typename BackendTraits::TextureType; using BackendType = typename BackendTraits::TextureType;
}; };
template<typename BackendTraits> template<typename BackendTraits>
struct ToBackendTraits<TextureViewBase, BackendTraits> { struct ToBackendTraits<TextureViewBase, BackendTraits> {
using BackendType = typename BackendTraits::TextureViewType; using BackendType = typename BackendTraits::TextureViewType;
}; };
// ToBackendBase implements conversion to the given BackendTraits // ToBackendBase implements conversion to the given BackendTraits
// To use it in a backend, use the following: // To use it in a backend, use the following:
// template<typename T> // template<typename T>
// auto ToBackend(T&& common) -> decltype(ToBackendBase<MyBackendTraits>(common)) { // auto ToBackend(T&& common) -> decltype(ToBackendBase<MyBackendTraits>(common)) {
// return ToBackendBase<MyBackendTraits>(common); // return ToBackendBase<MyBackendTraits>(common);
// } // }
template<typename BackendTraits, typename T> template<typename BackendTraits, typename T>
Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>& ToBackendBase(Ref<T>& common) { Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>& ToBackendBase(Ref<T>& common) {
return reinterpret_cast<Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>&>(common); return reinterpret_cast<Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>&>(common);
} }
template<typename BackendTraits, typename T> template<typename BackendTraits, typename T>
const Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>& ToBackendBase(const Ref<T>& common) { const Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>& ToBackendBase(const Ref<T>& common) {
return reinterpret_cast<const Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>&>(common); return reinterpret_cast<const Ref<typename ToBackendTraits<T, BackendTraits>::BackendType>&>(common);
} }
template<typename BackendTraits, typename T> template<typename BackendTraits, typename T>
typename ToBackendTraits<T, BackendTraits>::BackendType* ToBackendBase(T* common) { typename ToBackendTraits<T, BackendTraits>::BackendType* ToBackendBase(T* common) {
return reinterpret_cast<typename ToBackendTraits<T, BackendTraits>::BackendType*>(common); return reinterpret_cast<typename ToBackendTraits<T, BackendTraits>::BackendType*>(common);
} }
template<typename BackendTraits, typename T> template<typename BackendTraits, typename T>
const typename ToBackendTraits<T, BackendTraits>::BackendType* ToBackendBase(const T* common) { const typename ToBackendTraits<T, BackendTraits>::BackendType* ToBackendBase(const T* common) {
return reinterpret_cast<const typename ToBackendTraits<T, BackendTraits>::BackendType*>(common); return reinterpret_cast<const typename ToBackendTraits<T, BackendTraits>::BackendType*>(common);
} }
} }
#endif // BACKEND_COMMON_TOBACKEND_H_ #endif // BACKEND_COMMON_TOBACKEND_H_

View File

@ -667,48 +667,48 @@ namespace metal {
static MTLCompareFunction DepthStencilCompareFunction(nxt::CompareFunction compareFunction) { static MTLCompareFunction DepthStencilCompareFunction(nxt::CompareFunction compareFunction) {
switch (compareFunction) { switch (compareFunction) {
case nxt::CompareFunction::Never: case nxt::CompareFunction::Never:
return MTLCompareFunctionNever; return MTLCompareFunctionNever;
case nxt::CompareFunction::Less: case nxt::CompareFunction::Less:
return MTLCompareFunctionLess; return MTLCompareFunctionLess;
case nxt::CompareFunction::LessEqual: case nxt::CompareFunction::LessEqual:
return MTLCompareFunctionLessEqual; return MTLCompareFunctionLessEqual;
case nxt::CompareFunction::Greater: case nxt::CompareFunction::Greater:
return MTLCompareFunctionGreater; return MTLCompareFunctionGreater;
case nxt::CompareFunction::GreaterEqual: case nxt::CompareFunction::GreaterEqual:
return MTLCompareFunctionGreaterEqual; return MTLCompareFunctionGreaterEqual;
case nxt::CompareFunction::NotEqual: case nxt::CompareFunction::NotEqual:
return MTLCompareFunctionNotEqual; return MTLCompareFunctionNotEqual;
case nxt::CompareFunction::Equal: case nxt::CompareFunction::Equal:
return MTLCompareFunctionEqual; return MTLCompareFunctionEqual;
case nxt::CompareFunction::Always: case nxt::CompareFunction::Always:
return MTLCompareFunctionAlways; return MTLCompareFunctionAlways;
default: default:
ASSERT(false); ASSERT(false);
} }
} }
static MTLStencilOperation StencilOperation(nxt::StencilOperation stencilOperation) { static MTLStencilOperation StencilOperation(nxt::StencilOperation stencilOperation) {
switch (stencilOperation) { switch (stencilOperation) {
case nxt::StencilOperation::Keep: case nxt::StencilOperation::Keep:
return MTLStencilOperationKeep; return MTLStencilOperationKeep;
case nxt::StencilOperation::Zero: case nxt::StencilOperation::Zero:
return MTLStencilOperationZero; return MTLStencilOperationZero;
case nxt::StencilOperation::Replace: case nxt::StencilOperation::Replace:
return MTLStencilOperationReplace; return MTLStencilOperationReplace;
case nxt::StencilOperation::Invert: case nxt::StencilOperation::Invert:
return MTLStencilOperationInvert; return MTLStencilOperationInvert;
case nxt::StencilOperation::IncrementClamp: case nxt::StencilOperation::IncrementClamp:
return MTLStencilOperationIncrementClamp; return MTLStencilOperationIncrementClamp;
case nxt::StencilOperation::DecrementClamp: case nxt::StencilOperation::DecrementClamp:
return MTLStencilOperationDecrementClamp; return MTLStencilOperationDecrementClamp;
case nxt::StencilOperation::IncrementWrap: case nxt::StencilOperation::IncrementWrap:
return MTLStencilOperationIncrementWrap; return MTLStencilOperationIncrementWrap;
case nxt::StencilOperation::DecrementWrap: case nxt::StencilOperation::DecrementWrap:
return MTLStencilOperationDecrementWrap; return MTLStencilOperationDecrementWrap;
default: default:
ASSERT(false); ASSERT(false);
} }
} }
DepthStencilState::DepthStencilState(Device* device, DepthStencilStateBuilder* builder) DepthStencilState::DepthStencilState(Device* device, DepthStencilStateBuilder* builder)
@ -728,7 +728,7 @@ namespace metal {
default: default:
ASSERT(false); ASSERT(false);
break; break;
} }
} }
if (StencilIsEnabled()) { if (StencilIsEnabled()) {

View File

@ -1,123 +1,123 @@
// Copyright 2017 The NXT Authors // Copyright 2017 The NXT Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "NullBackend.h" #include "NullBackend.h"
#include <spirv-cross/spirv_cross.hpp> #include <spirv-cross/spirv_cross.hpp>
namespace backend { namespace backend {
namespace null { namespace null {
nxtProcTable GetNonValidatingProcs(); nxtProcTable GetNonValidatingProcs();
nxtProcTable GetValidatingProcs(); nxtProcTable GetValidatingProcs();
void Init(nxtProcTable* procs, nxtDevice* device) { void Init(nxtProcTable* procs, nxtDevice* device) {
*procs = GetValidatingProcs(); *procs = GetValidatingProcs();
*device = reinterpret_cast<nxtDevice>(new Device); *device = reinterpret_cast<nxtDevice>(new Device);
} }
// Device // Device
Device::Device() { Device::Device() {
} }
Device::~Device() { Device::~Device() {
} }
BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) { BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
return new BindGroupBase(builder); return new BindGroupBase(builder);
} }
BindGroupLayoutBase* Device::CreateBindGroupLayout(BindGroupLayoutBuilder* builder) { BindGroupLayoutBase* Device::CreateBindGroupLayout(BindGroupLayoutBuilder* builder) {
return new BindGroupLayoutBase(builder); return new BindGroupLayoutBase(builder);
} }
BufferBase* Device::CreateBuffer(BufferBuilder* builder) { BufferBase* Device::CreateBuffer(BufferBuilder* builder) {
return new Buffer(builder); return new Buffer(builder);
} }
BufferViewBase* Device::CreateBufferView(BufferViewBuilder* builder) { BufferViewBase* Device::CreateBufferView(BufferViewBuilder* builder) {
return new BufferViewBase(builder); return new BufferViewBase(builder);
} }
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) { CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
return new CommandBufferBase(builder); return new CommandBufferBase(builder);
} }
DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) { DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) {
return new DepthStencilStateBase(builder); return new DepthStencilStateBase(builder);
} }
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) { InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
return new InputStateBase(builder); return new InputStateBase(builder);
} }
FramebufferBase* Device::CreateFramebuffer(FramebufferBuilder* builder) { FramebufferBase* Device::CreateFramebuffer(FramebufferBuilder* builder) {
return new FramebufferBase(builder); return new FramebufferBase(builder);
} }
PipelineBase* Device::CreatePipeline(PipelineBuilder* builder) { PipelineBase* Device::CreatePipeline(PipelineBuilder* builder) {
return new PipelineBase(builder); return new PipelineBase(builder);
} }
PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) { PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) {
return new PipelineLayoutBase(builder); return new PipelineLayoutBase(builder);
} }
QueueBase* Device::CreateQueue(QueueBuilder* builder) { QueueBase* Device::CreateQueue(QueueBuilder* builder) {
return new Queue(builder); return new Queue(builder);
} }
RenderPassBase* Device::CreateRenderPass(RenderPassBuilder* builder) { RenderPassBase* Device::CreateRenderPass(RenderPassBuilder* builder) {
return new RenderPassBase(builder); return new RenderPassBase(builder);
} }
SamplerBase* Device::CreateSampler(SamplerBuilder* builder) { SamplerBase* Device::CreateSampler(SamplerBuilder* builder) {
return new SamplerBase(builder); return new SamplerBase(builder);
} }
ShaderModuleBase* Device::CreateShaderModule(ShaderModuleBuilder* builder) { ShaderModuleBase* Device::CreateShaderModule(ShaderModuleBuilder* builder) {
auto module = new ShaderModuleBase(builder); auto module = new ShaderModuleBase(builder);
spirv_cross::Compiler compiler(builder->AcquireSpirv()); spirv_cross::Compiler compiler(builder->AcquireSpirv());
module->ExtractSpirvInfo(compiler); module->ExtractSpirvInfo(compiler);
return module; return module;
} }
TextureBase* Device::CreateTexture(TextureBuilder* builder) { TextureBase* Device::CreateTexture(TextureBuilder* builder) {
return new TextureBase(builder); return new TextureBase(builder);
} }
TextureViewBase* Device::CreateTextureView(TextureViewBuilder* builder) { TextureViewBase* Device::CreateTextureView(TextureViewBuilder* builder) {
return new TextureViewBase(builder); return new TextureViewBase(builder);
} }
void Device::Reference() { void Device::Reference() {
} }
void Device::Release() { void Device::Release() {
} }
// Buffer // Buffer
Buffer::Buffer(BufferBuilder* builder) Buffer::Buffer(BufferBuilder* builder)
: BufferBase(builder) { : BufferBase(builder) {
} }
Buffer::~Buffer() { Buffer::~Buffer() {
} }
void Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) { void Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) {
} }
// Queue // Queue
Queue::Queue(QueueBuilder* builder) Queue::Queue(QueueBuilder* builder)
: QueueBase(builder) { : QueueBase(builder) {
} }
Queue::~Queue() { Queue::~Queue() {
} }
void Queue::Submit(uint32_t numCommands, CommandBuffer* const * commands) { void Queue::Submit(uint32_t numCommands, CommandBuffer* const * commands) {
} }
} }
} }

View File

@ -1,129 +1,129 @@
// Copyright 2017 The NXT Authors // Copyright 2017 The NXT Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef BACKEND_NULL_NULLBACKEND_H_ #ifndef BACKEND_NULL_NULLBACKEND_H_
#define BACKEND_NULL_NULLBACKEND_H_ #define BACKEND_NULL_NULLBACKEND_H_
#include "nxt/nxtcpp.h" #include "nxt/nxtcpp.h"
#include "common/Buffer.h" #include "common/Buffer.h"
#include "common/BindGroup.h" #include "common/BindGroup.h"
#include "common/BindGroupLayout.h" #include "common/BindGroupLayout.h"
#include "common/Device.h" #include "common/Device.h"
#include "common/CommandBuffer.h" #include "common/CommandBuffer.h"
#include "common/DepthStencilState.h" #include "common/DepthStencilState.h"
#include "common/InputState.h" #include "common/InputState.h"
#include "common/Framebuffer.h" #include "common/Framebuffer.h"
#include "common/Pipeline.h" #include "common/Pipeline.h"
#include "common/PipelineLayout.h" #include "common/PipelineLayout.h"
#include "common/Queue.h" #include "common/Queue.h"
#include "common/RenderPass.h" #include "common/RenderPass.h"
#include "common/Sampler.h" #include "common/Sampler.h"
#include "common/ShaderModule.h" #include "common/ShaderModule.h"
#include "common/Texture.h" #include "common/Texture.h"
#include "common/ToBackend.h" #include "common/ToBackend.h"
namespace backend { namespace backend {
namespace null { namespace null {
using BindGroup = BindGroupBase; using BindGroup = BindGroupBase;
using BindGroupLayout = BindGroupLayoutBase; using BindGroupLayout = BindGroupLayoutBase;
class Buffer; class Buffer;
using BufferView = BufferViewBase; using BufferView = BufferViewBase;
using CommandBuffer = CommandBufferBase; using CommandBuffer = CommandBufferBase;
using DepthStencilState = DepthStencilStateBase; using DepthStencilState = DepthStencilStateBase;
using InputState = InputStateBase; using InputState = InputStateBase;
using Framebuffer = FramebufferBase; using Framebuffer = FramebufferBase;
using Pipeline = PipelineBase; using Pipeline = PipelineBase;
using PipelineLayout = PipelineLayoutBase; using PipelineLayout = PipelineLayoutBase;
class Queue; class Queue;
using RenderPass = RenderPassBase; using RenderPass = RenderPassBase;
using Sampler = SamplerBase; using Sampler = SamplerBase;
using ShaderModule = ShaderModuleBase; using ShaderModule = ShaderModuleBase;
using Texture = TextureBase; using Texture = TextureBase;
using TextureView = TextureViewBase; using TextureView = TextureViewBase;
struct NullBackendTraits { struct NullBackendTraits {
using BindGroupType = BindGroup; using BindGroupType = BindGroup;
using BindGroupLayoutType = BindGroupLayout; using BindGroupLayoutType = BindGroupLayout;
using BufferType = Buffer; using BufferType = Buffer;
using BufferViewType = BufferView; using BufferViewType = BufferView;
using CommandBufferType = CommandBuffer; using CommandBufferType = CommandBuffer;
using DepthStencilStateType = DepthStencilState; using DepthStencilStateType = DepthStencilState;
using InputStateType = InputState; using InputStateType = InputState;
using FramebufferType = Framebuffer; using FramebufferType = Framebuffer;
using PipelineType = Pipeline; using PipelineType = Pipeline;
using PipelineLayoutType = PipelineLayout; using PipelineLayoutType = PipelineLayout;
using QueueType = Queue; using QueueType = Queue;
using RenderPassType = RenderPass; using RenderPassType = RenderPass;
using SamplerType = Sampler; using SamplerType = Sampler;
using ShaderModuleType = ShaderModule; using ShaderModuleType = ShaderModule;
using TextureType = Texture; using TextureType = Texture;
using TextureViewType = TextureView; using TextureViewType = TextureView;
}; };
template<typename T> template<typename T>
auto ToBackend(T&& common) -> decltype(ToBackendBase<NullBackendTraits>(common)) { auto ToBackend(T&& common) -> decltype(ToBackendBase<NullBackendTraits>(common)) {
return ToBackendBase<NullBackendTraits>(common); return ToBackendBase<NullBackendTraits>(common);
} }
class Device : public DeviceBase { class Device : public DeviceBase {
public: public:
Device(); Device();
~Device(); ~Device();
BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override; BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
BindGroupLayoutBase* CreateBindGroupLayout(BindGroupLayoutBuilder* builder) override; BindGroupLayoutBase* CreateBindGroupLayout(BindGroupLayoutBuilder* builder) override;
BufferBase* CreateBuffer(BufferBuilder* builder) override; BufferBase* CreateBuffer(BufferBuilder* builder) override;
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override; BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override; CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override; DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
InputStateBase* CreateInputState(InputStateBuilder* builder) override; InputStateBase* CreateInputState(InputStateBuilder* builder) override;
FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override; FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override;
PipelineBase* CreatePipeline(PipelineBuilder* builder) override; PipelineBase* CreatePipeline(PipelineBuilder* builder) override;
PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override; PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override;
QueueBase* CreateQueue(QueueBuilder* builder) override; QueueBase* CreateQueue(QueueBuilder* builder) override;
RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) override; RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) override;
SamplerBase* CreateSampler(SamplerBuilder* builder) override; SamplerBase* CreateSampler(SamplerBuilder* builder) override;
ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override; ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override;
TextureBase* CreateTexture(TextureBuilder* builder) override; TextureBase* CreateTexture(TextureBuilder* builder) override;
TextureViewBase* CreateTextureView(TextureViewBuilder* builder) override; TextureViewBase* CreateTextureView(TextureViewBuilder* builder) override;
// NXT API // NXT API
void Reference(); void Reference();
void Release(); void Release();
}; };
class Buffer : public BufferBase { class Buffer : public BufferBase {
public: public:
Buffer(BufferBuilder* builder); Buffer(BufferBuilder* builder);
~Buffer(); ~Buffer();
private: private:
void SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) override; void SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) override;
}; };
class Queue : public QueueBase { class Queue : public QueueBase {
public: public:
Queue(QueueBuilder* builder); Queue(QueueBuilder* builder);
~Queue(); ~Queue();
// NXT API // NXT API
void Submit(uint32_t numCommands, CommandBuffer* const * commands); void Submit(uint32_t numCommands, CommandBuffer* const * commands);
}; };
} }
} }
#endif // BACKEND_NULL_NULLBACKEND_H_ #endif // BACKEND_NULL_NULLBACKEND_H_

View File

@ -177,14 +177,14 @@ namespace opengl {
} }
} }
break; break;
case Command::SetStencilReference: case Command::SetStencilReference:
{ {
SetStencilReferenceCmd* cmd = commands.NextCommand<SetStencilReferenceCmd>(); SetStencilReferenceCmd* cmd = commands.NextCommand<SetStencilReferenceCmd>();
DepthStencilState* depthStencilState = ToBackend(lastPipeline->GetDepthStencilState()); DepthStencilState* depthStencilState = ToBackend(lastPipeline->GetDepthStencilState());
depthStencilState->ApplyStencilReferenceNow(cmd->backReference, cmd->frontReference); depthStencilState->ApplyStencilReferenceNow(cmd->backReference, cmd->frontReference);
} }
break; break;
case Command::SetBindGroup: case Command::SetBindGroup:
{ {

View File

@ -1,319 +1,319 @@
// Copyright 2017 The NXT Authors // Copyright 2017 The NXT Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "OpenGLBackend.h" #include "OpenGLBackend.h"
#include "CommandBufferGL.h" #include "CommandBufferGL.h"
#include "PipelineGL.h" #include "PipelineGL.h"
#include "PipelineLayoutGL.h" #include "PipelineLayoutGL.h"
#include "ShaderModuleGL.h" #include "ShaderModuleGL.h"
#include "SamplerGL.h" #include "SamplerGL.h"
#include "TextureGL.h" #include "TextureGL.h"
namespace backend { namespace backend {
namespace opengl { namespace opengl {
nxtProcTable GetNonValidatingProcs(); nxtProcTable GetNonValidatingProcs();
nxtProcTable GetValidatingProcs(); nxtProcTable GetValidatingProcs();
void HACKCLEAR() { void HACKCLEAR() {
glClearColor(0, 0, 0, 1); glClearColor(0, 0, 0, 1);
glStencilMask(0xff); glStencilMask(0xff);
glClearStencil(0); glClearStencil(0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
} }
void Init(void* (*getProc)(const char*), nxtProcTable* procs, nxtDevice* device) { void Init(void* (*getProc)(const char*), nxtProcTable* procs, nxtDevice* device) {
*device = nullptr; *device = nullptr;
gladLoadGLLoader(reinterpret_cast<GLADloadproc>(getProc)); gladLoadGLLoader(reinterpret_cast<GLADloadproc>(getProc));
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
HACKCLEAR(); HACKCLEAR();
*procs = GetValidatingProcs(); *procs = GetValidatingProcs();
*device = reinterpret_cast<nxtDevice>(new Device); *device = reinterpret_cast<nxtDevice>(new Device);
} }
static GLuint OpenGLCompareFunction(nxt::CompareFunction compareFunction) { static GLuint OpenGLCompareFunction(nxt::CompareFunction compareFunction) {
switch (compareFunction) { switch (compareFunction) {
case nxt::CompareFunction::Never: case nxt::CompareFunction::Never:
return GL_NEVER; return GL_NEVER;
case nxt::CompareFunction::Less: case nxt::CompareFunction::Less:
return GL_LESS; return GL_LESS;
case nxt::CompareFunction::LessEqual: case nxt::CompareFunction::LessEqual:
return GL_LEQUAL; return GL_LEQUAL;
case nxt::CompareFunction::Greater: case nxt::CompareFunction::Greater:
return GL_GREATER; return GL_GREATER;
case nxt::CompareFunction::GreaterEqual: case nxt::CompareFunction::GreaterEqual:
return GL_GEQUAL; return GL_GEQUAL;
case nxt::CompareFunction::NotEqual: case nxt::CompareFunction::NotEqual:
return GL_NOTEQUAL; return GL_NOTEQUAL;
case nxt::CompareFunction::Equal: case nxt::CompareFunction::Equal:
return GL_EQUAL; return GL_EQUAL;
case nxt::CompareFunction::Always: case nxt::CompareFunction::Always:
return GL_ALWAYS; return GL_ALWAYS;
default: default:
ASSERT(false); ASSERT(false);
} }
} }
static GLuint OpenGLStencilOperation(nxt::StencilOperation stencilOperation) { static GLuint OpenGLStencilOperation(nxt::StencilOperation stencilOperation) {
switch (stencilOperation) { switch (stencilOperation) {
case nxt::StencilOperation::Keep: case nxt::StencilOperation::Keep:
return GL_KEEP; return GL_KEEP;
case nxt::StencilOperation::Zero: case nxt::StencilOperation::Zero:
return GL_ZERO; return GL_ZERO;
case nxt::StencilOperation::Replace: case nxt::StencilOperation::Replace:
return GL_REPLACE; return GL_REPLACE;
case nxt::StencilOperation::Invert: case nxt::StencilOperation::Invert:
return GL_INVERT; return GL_INVERT;
case nxt::StencilOperation::IncrementClamp: case nxt::StencilOperation::IncrementClamp:
return GL_INCR; return GL_INCR;
case nxt::StencilOperation::DecrementClamp: case nxt::StencilOperation::DecrementClamp:
return GL_DECR; return GL_DECR;
case nxt::StencilOperation::IncrementWrap: case nxt::StencilOperation::IncrementWrap:
return GL_INCR_WRAP; return GL_INCR_WRAP;
case nxt::StencilOperation::DecrementWrap: case nxt::StencilOperation::DecrementWrap:
return GL_DECR_WRAP; return GL_DECR_WRAP;
default: default:
ASSERT(false); ASSERT(false);
} }
} }
// Device // Device
BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) { BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
return new BindGroup(this, builder); return new BindGroup(this, builder);
} }
BindGroupLayoutBase* Device::CreateBindGroupLayout(BindGroupLayoutBuilder* builder) { BindGroupLayoutBase* Device::CreateBindGroupLayout(BindGroupLayoutBuilder* builder) {
return new BindGroupLayout(this, builder); return new BindGroupLayout(this, builder);
} }
BufferBase* Device::CreateBuffer(BufferBuilder* builder) { BufferBase* Device::CreateBuffer(BufferBuilder* builder) {
return new Buffer(this, builder); return new Buffer(this, builder);
} }
BufferViewBase* Device::CreateBufferView(BufferViewBuilder* builder) { BufferViewBase* Device::CreateBufferView(BufferViewBuilder* builder) {
return new BufferView(this, builder); return new BufferView(this, builder);
} }
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) { CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
return new CommandBuffer(this, builder); return new CommandBuffer(this, builder);
} }
DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) { DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) {
return new DepthStencilState(this, builder); return new DepthStencilState(this, builder);
} }
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) { InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
return new InputState(this, builder); return new InputState(this, builder);
} }
FramebufferBase* Device::CreateFramebuffer(FramebufferBuilder* builder) { FramebufferBase* Device::CreateFramebuffer(FramebufferBuilder* builder) {
return new Framebuffer(this, builder); return new Framebuffer(this, builder);
} }
PipelineBase* Device::CreatePipeline(PipelineBuilder* builder) { PipelineBase* Device::CreatePipeline(PipelineBuilder* builder) {
return new Pipeline(this, builder); return new Pipeline(this, builder);
} }
PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) { PipelineLayoutBase* Device::CreatePipelineLayout(PipelineLayoutBuilder* builder) {
return new PipelineLayout(this, builder); return new PipelineLayout(this, builder);
} }
QueueBase* Device::CreateQueue(QueueBuilder* builder) { QueueBase* Device::CreateQueue(QueueBuilder* builder) {
return new Queue(this, builder); return new Queue(this, builder);
} }
RenderPassBase* Device::CreateRenderPass(RenderPassBuilder* builder) { RenderPassBase* Device::CreateRenderPass(RenderPassBuilder* builder) {
return new RenderPass(this, builder); return new RenderPass(this, builder);
} }
SamplerBase* Device::CreateSampler(SamplerBuilder* builder) { SamplerBase* Device::CreateSampler(SamplerBuilder* builder) {
return new Sampler(this, builder); return new Sampler(this, builder);
} }
ShaderModuleBase* Device::CreateShaderModule(ShaderModuleBuilder* builder) { ShaderModuleBase* Device::CreateShaderModule(ShaderModuleBuilder* builder) {
return new ShaderModule(this, builder); return new ShaderModule(this, builder);
} }
TextureBase* Device::CreateTexture(TextureBuilder* builder) { TextureBase* Device::CreateTexture(TextureBuilder* builder) {
return new Texture(this, builder); return new Texture(this, builder);
} }
TextureViewBase* Device::CreateTextureView(TextureViewBuilder* builder) { TextureViewBase* Device::CreateTextureView(TextureViewBuilder* builder) {
return new TextureView(this, builder); return new TextureView(this, builder);
} }
void Device::Reference() { void Device::Reference() {
} }
void Device::Release() { void Device::Release() {
} }
// Bind Group // Bind Group
BindGroup::BindGroup(Device* device, BindGroupBuilder* builder) BindGroup::BindGroup(Device* device, BindGroupBuilder* builder)
: BindGroupBase(builder), device(device) { : BindGroupBase(builder), device(device) {
} }
// Bind Group Layout // Bind Group Layout
BindGroupLayout::BindGroupLayout(Device* device, BindGroupLayoutBuilder* builder) BindGroupLayout::BindGroupLayout(Device* device, BindGroupLayoutBuilder* builder)
: BindGroupLayoutBase(builder), device(device) { : BindGroupLayoutBase(builder), device(device) {
} }
// Buffer // Buffer
Buffer::Buffer(Device* device, BufferBuilder* builder) Buffer::Buffer(Device* device, BufferBuilder* builder)
: BufferBase(builder), device(device) { : BufferBase(builder), device(device) {
glGenBuffers(1, &buffer); glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, GetSize(), nullptr, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, GetSize(), nullptr, GL_STATIC_DRAW);
} }
GLuint Buffer::GetHandle() const { GLuint Buffer::GetHandle() const {
return buffer; return buffer;
} }
void Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) { void Buffer::SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) {
glBindBuffer(GL_ARRAY_BUFFER, buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferSubData(GL_ARRAY_BUFFER, start * sizeof(uint32_t), count * sizeof(uint32_t), data); glBufferSubData(GL_ARRAY_BUFFER, start * sizeof(uint32_t), count * sizeof(uint32_t), data);
} }
// BufferView // BufferView
BufferView::BufferView(Device* device, BufferViewBuilder* builder) BufferView::BufferView(Device* device, BufferViewBuilder* builder)
: BufferViewBase(builder), device(device) { : BufferViewBase(builder), device(device) {
} }
// DepthStencilState // DepthStencilState
DepthStencilState::DepthStencilState(Device* device, DepthStencilStateBuilder* builder) DepthStencilState::DepthStencilState(Device* device, DepthStencilStateBuilder* builder)
: DepthStencilStateBase(builder), device(device) { : DepthStencilStateBase(builder), device(device) {
} }
void DepthStencilState::ApplyNow() { void DepthStencilState::ApplyNow() {
if (DepthIsEnabled()) { if (DepthIsEnabled()) {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
auto& depth = GetDepth(); auto& depth = GetDepth();
glDepthFunc(OpenGLCompareFunction(depth.compareFunction)); glDepthFunc(OpenGLCompareFunction(depth.compareFunction));
switch (depth.depthWriteMode) { switch (depth.depthWriteMode) {
case nxt::DepthWriteMode::Disabled: case nxt::DepthWriteMode::Disabled:
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
break; break;
case nxt::DepthWriteMode::Enabled: case nxt::DepthWriteMode::Enabled:
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
break; break;
default: default:
ASSERT(false); ASSERT(false);
break; break;
} }
} }
else { else {
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
} }
if (StencilIsEnabled()) { if (StencilIsEnabled()) {
glEnable(GL_STENCIL_TEST); glEnable(GL_STENCIL_TEST);
auto& back = GetStencil(nxt::Face::Back); auto& back = GetStencil(nxt::Face::Back);
auto& front = GetStencil(nxt::Face::Front); auto& front = GetStencil(nxt::Face::Front);
glStencilOpSeparate(GL_BACK, glStencilOpSeparate(GL_BACK,
OpenGLStencilOperation(back.stencilFail), OpenGLStencilOperation(back.stencilFail),
OpenGLStencilOperation(back.depthFail), OpenGLStencilOperation(back.depthFail),
OpenGLStencilOperation(back.stencilPass) OpenGLStencilOperation(back.stencilPass)
); );
glStencilOpSeparate(GL_FRONT, glStencilOpSeparate(GL_FRONT,
OpenGLStencilOperation(front.stencilFail), OpenGLStencilOperation(front.stencilFail),
OpenGLStencilOperation(front.depthFail), OpenGLStencilOperation(front.depthFail),
OpenGLStencilOperation(front.stencilPass) OpenGLStencilOperation(front.stencilPass)
); );
glStencilMaskSeparate(GL_BACK, back.writeMask); glStencilMaskSeparate(GL_BACK, back.writeMask);
glStencilMaskSeparate(GL_FRONT, front.writeMask); glStencilMaskSeparate(GL_FRONT, front.writeMask);
} }
else { else {
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
} }
} }
void DepthStencilState::ApplyStencilReferenceNow(uint32_t backReference, uint32_t frontReference) { void DepthStencilState::ApplyStencilReferenceNow(uint32_t backReference, uint32_t frontReference) {
if (StencilIsEnabled()) { if (StencilIsEnabled()) {
auto& back = GetStencil(nxt::Face::Back); auto& back = GetStencil(nxt::Face::Back);
auto& front = GetStencil(nxt::Face::Front); auto& front = GetStencil(nxt::Face::Front);
glStencilFuncSeparate(GL_BACK, glStencilFuncSeparate(GL_BACK,
OpenGLCompareFunction(back.compareFunction), OpenGLCompareFunction(back.compareFunction),
backReference, backReference,
back.readMask back.readMask
); );
glStencilFuncSeparate(GL_FRONT, glStencilFuncSeparate(GL_FRONT,
OpenGLCompareFunction(front.compareFunction), OpenGLCompareFunction(front.compareFunction),
frontReference, frontReference,
front.readMask front.readMask
); );
} }
} }
// InputState // InputState
InputState::InputState(Device* device, InputStateBuilder* builder) InputState::InputState(Device* device, InputStateBuilder* builder)
: InputStateBase(builder), device(device) { : InputStateBase(builder), device(device) {
glGenVertexArrays(1, &vertexArrayObject); glGenVertexArrays(1, &vertexArrayObject);
glBindVertexArray(vertexArrayObject); glBindVertexArray(vertexArrayObject);
auto& attributesSetMask = GetAttributesSetMask(); auto& attributesSetMask = GetAttributesSetMask();
for (uint32_t location = 0; location < attributesSetMask.size(); ++location) { for (uint32_t location = 0; location < attributesSetMask.size(); ++location) {
if (!attributesSetMask[location]) { if (!attributesSetMask[location]) {
continue; continue;
} }
auto attribute = GetAttribute(location); auto attribute = GetAttribute(location);
glEnableVertexAttribArray(location); glEnableVertexAttribArray(location);
auto input = GetInput(attribute.bindingSlot); auto input = GetInput(attribute.bindingSlot);
if (input.stride == 0) { if (input.stride == 0) {
// Emulate a stride of zero (constant vertex attribute) by // Emulate a stride of zero (constant vertex attribute) by
// setting the attribute instance divisor to a huge number. // setting the attribute instance divisor to a huge number.
glVertexAttribDivisor(location, 0xffffffff); glVertexAttribDivisor(location, 0xffffffff);
} else { } else {
switch (input.stepMode) { switch (input.stepMode) {
case nxt::InputStepMode::Vertex: case nxt::InputStepMode::Vertex:
break; break;
case nxt::InputStepMode::Instance: case nxt::InputStepMode::Instance:
glVertexAttribDivisor(location, 1); glVertexAttribDivisor(location, 1);
break; break;
default: default:
ASSERT(false); ASSERT(false);
break; break;
} }
} }
} }
} }
GLuint InputState::GetVAO() { GLuint InputState::GetVAO() {
return vertexArrayObject; return vertexArrayObject;
} }
// Framebuffer // Framebuffer
Framebuffer::Framebuffer(Device* device, FramebufferBuilder* builder) Framebuffer::Framebuffer(Device* device, FramebufferBuilder* builder)
: FramebufferBase(builder), device(device) { : FramebufferBase(builder), device(device) {
} }
// Queue // Queue
Queue::Queue(Device* device, QueueBuilder* builder) Queue::Queue(Device* device, QueueBuilder* builder)
: QueueBase(builder), device(device) { : QueueBase(builder), device(device) {
} }
void Queue::Submit(uint32_t numCommands, CommandBuffer* const * commands) { void Queue::Submit(uint32_t numCommands, CommandBuffer* const * commands) {
for (uint32_t i = 0; i < numCommands; ++i) { for (uint32_t i = 0; i < numCommands; ++i) {
commands[i]->Execute(); commands[i]->Execute();
} }
} }
// RenderPass // RenderPass
RenderPass::RenderPass(Device* device, RenderPassBuilder* builder) RenderPass::RenderPass(Device* device, RenderPassBuilder* builder)
: RenderPassBase(builder), device(device) { : RenderPassBase(builder), device(device) {
} }
} }
} }

View File

@ -1,189 +1,189 @@
// Copyright 2017 The NXT Authors // Copyright 2017 The NXT Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef BACKEND_OPENGL_OPENGLBACKEND_H_ #ifndef BACKEND_OPENGL_OPENGLBACKEND_H_
#define BACKEND_OPENGL_OPENGLBACKEND_H_ #define BACKEND_OPENGL_OPENGLBACKEND_H_
#include "nxt/nxtcpp.h" #include "nxt/nxtcpp.h"
#include "common/Buffer.h" #include "common/Buffer.h"
#include "common/BindGroup.h" #include "common/BindGroup.h"
#include "common/BindGroupLayout.h" #include "common/BindGroupLayout.h"
#include "common/Device.h" #include "common/Device.h"
#include "common/DepthStencilState.h" #include "common/DepthStencilState.h"
#include "common/Framebuffer.h" #include "common/Framebuffer.h"
#include "common/InputState.h" #include "common/InputState.h"
#include "common/Queue.h" #include "common/Queue.h"
#include "common/RenderPass.h" #include "common/RenderPass.h"
#include "common/ToBackend.h" #include "common/ToBackend.h"
#include "glad/glad.h" #include "glad/glad.h"
namespace backend { namespace backend {
namespace opengl { namespace opengl {
class BindGroup; class BindGroup;
class BindGroupLayout; class BindGroupLayout;
class Buffer; class Buffer;
class BufferView; class BufferView;
class CommandBuffer; class CommandBuffer;
class DepthStencilState; class DepthStencilState;
class InputState; class InputState;
class Pipeline; class Pipeline;
class PipelineLayout; class PipelineLayout;
class Queue; class Queue;
class Sampler; class Sampler;
class ShaderModule; class ShaderModule;
class Texture; class Texture;
class TextureView; class TextureView;
class Framebuffer; class Framebuffer;
class RenderPass; class RenderPass;
struct OpenGLBackendTraits { struct OpenGLBackendTraits {
using BindGroupType = BindGroup; using BindGroupType = BindGroup;
using BindGroupLayoutType = BindGroupLayout; using BindGroupLayoutType = BindGroupLayout;
using BufferType = Buffer; using BufferType = Buffer;
using BufferViewType = BufferView; using BufferViewType = BufferView;
using CommandBufferType = CommandBuffer; using CommandBufferType = CommandBuffer;
using DepthStencilStateType = DepthStencilState; using DepthStencilStateType = DepthStencilState;
using InputStateType = InputState; using InputStateType = InputState;
using PipelineType = Pipeline; using PipelineType = Pipeline;
using PipelineLayoutType = PipelineLayout; using PipelineLayoutType = PipelineLayout;
using QueueType = Queue; using QueueType = Queue;
using SamplerType = Sampler; using SamplerType = Sampler;
using ShaderModuleType = ShaderModule; using ShaderModuleType = ShaderModule;
using TextureType = Texture; using TextureType = Texture;
using TextureViewType = TextureView; using TextureViewType = TextureView;
using FramebufferType = Framebuffer; using FramebufferType = Framebuffer;
using RenderPassType = RenderPass; using RenderPassType = RenderPass;
}; };
template<typename T> template<typename T>
auto ToBackend(T&& common) -> decltype(ToBackendBase<OpenGLBackendTraits>(common)) { auto ToBackend(T&& common) -> decltype(ToBackendBase<OpenGLBackendTraits>(common)) {
return ToBackendBase<OpenGLBackendTraits>(common); return ToBackendBase<OpenGLBackendTraits>(common);
} }
// Definition of backend types // Definition of backend types
class Device : public DeviceBase { class Device : public DeviceBase {
public: public:
BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override; BindGroupBase* CreateBindGroup(BindGroupBuilder* builder) override;
BindGroupLayoutBase* CreateBindGroupLayout(BindGroupLayoutBuilder* builder) override; BindGroupLayoutBase* CreateBindGroupLayout(BindGroupLayoutBuilder* builder) override;
BufferBase* CreateBuffer(BufferBuilder* builder) override; BufferBase* CreateBuffer(BufferBuilder* builder) override;
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override; BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override; CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override; DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
InputStateBase* CreateInputState(InputStateBuilder* builder) override; InputStateBase* CreateInputState(InputStateBuilder* builder) override;
FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override; FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override;
PipelineBase* CreatePipeline(PipelineBuilder* builder) override; PipelineBase* CreatePipeline(PipelineBuilder* builder) override;
PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override; PipelineLayoutBase* CreatePipelineLayout(PipelineLayoutBuilder* builder) override;
QueueBase* CreateQueue(QueueBuilder* builder) override; QueueBase* CreateQueue(QueueBuilder* builder) override;
RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) override; RenderPassBase* CreateRenderPass(RenderPassBuilder* builder) override;
SamplerBase* CreateSampler(SamplerBuilder* builder) override; SamplerBase* CreateSampler(SamplerBuilder* builder) override;
ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override; ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override;
TextureBase* CreateTexture(TextureBuilder* builder) override; TextureBase* CreateTexture(TextureBuilder* builder) override;
TextureViewBase* CreateTextureView(TextureViewBuilder* builder) override; TextureViewBase* CreateTextureView(TextureViewBuilder* builder) override;
// NXT API // NXT API
void Reference(); void Reference();
void Release(); void Release();
}; };
class BindGroup : public BindGroupBase { class BindGroup : public BindGroupBase {
public: public:
BindGroup(Device* device, BindGroupBuilder* builder); BindGroup(Device* device, BindGroupBuilder* builder);
private: private:
Device* device; Device* device;
}; };
class BindGroupLayout : public BindGroupLayoutBase { class BindGroupLayout : public BindGroupLayoutBase {
public: public:
BindGroupLayout(Device* device, BindGroupLayoutBuilder* builder); BindGroupLayout(Device* device, BindGroupLayoutBuilder* builder);
private: private:
Device* device; Device* device;
}; };
class Buffer : public BufferBase { class Buffer : public BufferBase {
public: public:
Buffer(Device* device, BufferBuilder* builder); Buffer(Device* device, BufferBuilder* builder);
GLuint GetHandle() const; GLuint GetHandle() const;
private: private:
void SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) override; void SetSubDataImpl(uint32_t start, uint32_t count, const uint32_t* data) override;
Device* device; Device* device;
GLuint buffer = 0; GLuint buffer = 0;
}; };
class BufferView : public BufferViewBase { class BufferView : public BufferViewBase {
public: public:
BufferView(Device* device, BufferViewBuilder* builder); BufferView(Device* device, BufferViewBuilder* builder);
private: private:
Device* device; Device* device;
}; };
class DepthStencilState : public DepthStencilStateBase { class DepthStencilState : public DepthStencilStateBase {
public: public:
DepthStencilState(Device* device, DepthStencilStateBuilder* builder); DepthStencilState(Device* device, DepthStencilStateBuilder* builder);
void ApplyNow(); void ApplyNow();
void ApplyStencilReferenceNow(uint32_t backReference, uint32_t frontReference); void ApplyStencilReferenceNow(uint32_t backReference, uint32_t frontReference);
private: private:
Device* device; Device* device;
}; };
class Framebuffer : public FramebufferBase { class Framebuffer : public FramebufferBase {
public: public:
Framebuffer(Device* device, FramebufferBuilder* builder); Framebuffer(Device* device, FramebufferBuilder* builder);
private: private:
Device* device; Device* device;
}; };
class InputState : public InputStateBase { class InputState : public InputStateBase {
public: public:
InputState(Device* device, InputStateBuilder* builder); InputState(Device* device, InputStateBuilder* builder);
GLuint GetVAO(); GLuint GetVAO();
private: private:
Device* device; Device* device;
GLuint vertexArrayObject; GLuint vertexArrayObject;
}; };
class Queue : public QueueBase { class Queue : public QueueBase {
public: public:
Queue(Device* device, QueueBuilder* builder); Queue(Device* device, QueueBuilder* builder);
// NXT API // NXT API
void Submit(uint32_t numCommands, CommandBuffer* const * commands); void Submit(uint32_t numCommands, CommandBuffer* const * commands);
private: private:
Device* device; Device* device;
}; };
class RenderPass : public RenderPassBase { class RenderPass : public RenderPassBase {
public: public:
RenderPass(Device* device, RenderPassBuilder* builder); RenderPass(Device* device, RenderPassBuilder* builder);
private: private:
Device* device; Device* device;
}; };
} }
} }
#endif // BACKEND_OPENGL_OPENGLBACKEND_H_ #endif // BACKEND_OPENGL_OPENGLBACKEND_H_

View File

@ -1,215 +1,215 @@
// Copyright 2017 The NXT Authors // Copyright 2017 The NXT Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
// You may obtain a copy of the License at // You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, software // Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "PipelineGL.h" #include "PipelineGL.h"
#include "OpenGLBackend.h" #include "OpenGLBackend.h"
#include "PipelineLayoutGL.h" #include "PipelineLayoutGL.h"
#include "ShaderModuleGL.h" #include "ShaderModuleGL.h"
#include <iostream> #include <iostream>
#include <set> #include <set>
namespace backend { namespace backend {
namespace opengl { namespace opengl {
namespace { namespace {
GLenum GLShaderType(nxt::ShaderStage stage) { GLenum GLShaderType(nxt::ShaderStage stage) {
switch (stage) { switch (stage) {
case nxt::ShaderStage::Vertex: case nxt::ShaderStage::Vertex:
return GL_VERTEX_SHADER; return GL_VERTEX_SHADER;
case nxt::ShaderStage::Fragment: case nxt::ShaderStage::Fragment:
return GL_FRAGMENT_SHADER; return GL_FRAGMENT_SHADER;
case nxt::ShaderStage::Compute: case nxt::ShaderStage::Compute:
return GL_COMPUTE_SHADER; return GL_COMPUTE_SHADER;
} }
} }
} }
Pipeline::Pipeline(Device* device, PipelineBuilder* builder) : PipelineBase(builder), device(device) { Pipeline::Pipeline(Device* device, PipelineBuilder* builder) : PipelineBase(builder), device(device) {
auto CreateShader = [](GLenum type, const char* source) -> GLuint { auto CreateShader = [](GLenum type, const char* source) -> GLuint {
GLuint shader = glCreateShader(type); GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &source, nullptr); glShaderSource(shader, 1, &source, nullptr);
glCompileShader(shader); glCompileShader(shader);
GLint compileStatus = GL_FALSE; GLint compileStatus = GL_FALSE;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus); glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
if (compileStatus == GL_FALSE) { if (compileStatus == GL_FALSE) {
GLint infoLogLength = 0; GLint infoLogLength = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength); glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
if (infoLogLength > 1) { if (infoLogLength > 1) {
std::vector<char> buffer(infoLogLength); std::vector<char> buffer(infoLogLength);
glGetShaderInfoLog(shader, infoLogLength, nullptr, &buffer[0]); glGetShaderInfoLog(shader, infoLogLength, nullptr, &buffer[0]);
std::cout << source << std::endl; std::cout << source << std::endl;
std::cout << "Program compilation failed:\n"; std::cout << "Program compilation failed:\n";
std::cout << buffer.data() << std::endl; std::cout << buffer.data() << std::endl;
} }
} }
return shader; return shader;
}; };
auto FillPushConstants = [](const ShaderModule* module, GLPushConstantInfo* info, GLuint program) { auto FillPushConstants = [](const ShaderModule* module, GLPushConstantInfo* info, GLuint program) {
const auto& moduleInfo = module->GetPushConstants(); const auto& moduleInfo = module->GetPushConstants();
for (uint32_t i = 0; i < moduleInfo.names.size(); i++) { for (uint32_t i = 0; i < moduleInfo.names.size(); i++) {
(*info)[i] = -1; (*info)[i] = -1;
unsigned int size = moduleInfo.sizes[i]; unsigned int size = moduleInfo.sizes[i];
if (size == 0) { if (size == 0) {
continue; continue;
} }
GLint location = glGetUniformLocation(program, moduleInfo.names[i].c_str()); GLint location = glGetUniformLocation(program, moduleInfo.names[i].c_str());
if (location == -1) { if (location == -1) {
continue; continue;
} }
for (uint32_t offset = 0; offset < size; offset++) { for (uint32_t offset = 0; offset < size; offset++) {
(*info)[i + offset] = location + offset; (*info)[i + offset] = location + offset;
} }
i += size - 1; i += size - 1;
} }
}; };
program = glCreateProgram(); program = glCreateProgram();
for (auto stage : IterateStages(GetStageMask())) { for (auto stage : IterateStages(GetStageMask())) {
const ShaderModule* module = ToBackend(builder->GetStageInfo(stage).module.Get()); const ShaderModule* module = ToBackend(builder->GetStageInfo(stage).module.Get());
GLuint shader = CreateShader(GLShaderType(stage), module->GetSource()); GLuint shader = CreateShader(GLShaderType(stage), module->GetSource());
glAttachShader(program, shader); glAttachShader(program, shader);
} }
glLinkProgram(program); glLinkProgram(program);
GLint linkStatus = GL_FALSE; GLint linkStatus = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (linkStatus == GL_FALSE) { if (linkStatus == GL_FALSE) {
GLint infoLogLength = 0; GLint infoLogLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength); glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
if (infoLogLength > 1) { if (infoLogLength > 1) {
std::vector<char> buffer(infoLogLength); std::vector<char> buffer(infoLogLength);
glGetProgramInfoLog(program, infoLogLength, nullptr, &buffer[0]); glGetProgramInfoLog(program, infoLogLength, nullptr, &buffer[0]);
std::cout << "Program link failed:\n"; std::cout << "Program link failed:\n";
std::cout << buffer.data() << std::endl; std::cout << buffer.data() << std::endl;
} }
} }
for (auto stage : IterateStages(GetStageMask())) { for (auto stage : IterateStages(GetStageMask())) {
const ShaderModule* module = ToBackend(builder->GetStageInfo(stage).module.Get()); const ShaderModule* module = ToBackend(builder->GetStageInfo(stage).module.Get());
FillPushConstants(module, &glPushConstants[stage], program); FillPushConstants(module, &glPushConstants[stage], program);
} }
glUseProgram(program); glUseProgram(program);
// The uniforms are part of the program state so we can pre-bind buffer units, texture units etc. // The uniforms are part of the program state so we can pre-bind buffer units, texture units etc.
const auto& layout = ToBackend(GetLayout()); const auto& layout = ToBackend(GetLayout());
const auto& indices = layout->GetBindingIndexInfo(); const auto& indices = layout->GetBindingIndexInfo();
for (uint32_t group = 0; group < kMaxBindGroups; ++group) { for (uint32_t group = 0; group < kMaxBindGroups; ++group) {
const auto& groupInfo = layout->GetBindGroupLayout(group)->GetBindingInfo(); const auto& groupInfo = layout->GetBindGroupLayout(group)->GetBindingInfo();
for (uint32_t binding = 0; binding < kMaxBindingsPerGroup; ++binding) { for (uint32_t binding = 0; binding < kMaxBindingsPerGroup; ++binding) {
if (!groupInfo.mask[binding]) { if (!groupInfo.mask[binding]) {
continue; continue;
} }
std::string name = GetBindingName(group, binding); std::string name = GetBindingName(group, binding);
switch (groupInfo.types[binding]) { switch (groupInfo.types[binding]) {
case nxt::BindingType::UniformBuffer: case nxt::BindingType::UniformBuffer:
{ {
GLint location = glGetUniformBlockIndex(program, name.c_str()); GLint location = glGetUniformBlockIndex(program, name.c_str());
glUniformBlockBinding(program, location, indices[group][binding]); glUniformBlockBinding(program, location, indices[group][binding]);
} }
break; break;
case nxt::BindingType::StorageBuffer: case nxt::BindingType::StorageBuffer:
{ {
GLuint location = glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, name.c_str()); GLuint location = glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, name.c_str());
glShaderStorageBlockBinding(program, location, indices[group][binding]); glShaderStorageBlockBinding(program, location, indices[group][binding]);
} }
break; break;
case nxt::BindingType::Sampler: case nxt::BindingType::Sampler:
case nxt::BindingType::SampledTexture: case nxt::BindingType::SampledTexture:
// These binding types are handled in the separate sampler and texture emulation // These binding types are handled in the separate sampler and texture emulation
break; break;
} }
} }
} }
// Compute links between stages for combined samplers, then bind them to texture units // Compute links between stages for combined samplers, then bind them to texture units
{ {
std::set<CombinedSampler> combinedSamplersSet; std::set<CombinedSampler> combinedSamplersSet;
for (auto stage : IterateStages(GetStageMask())) { for (auto stage : IterateStages(GetStageMask())) {
const auto& module = ToBackend(builder->GetStageInfo(stage).module); const auto& module = ToBackend(builder->GetStageInfo(stage).module);
for (const auto& combined : module->GetCombinedSamplerInfo()) { for (const auto& combined : module->GetCombinedSamplerInfo()) {
combinedSamplersSet.insert(combined); combinedSamplersSet.insert(combined);
} }
} }
unitsForSamplers.resize(layout->GetNumSamplers()); unitsForSamplers.resize(layout->GetNumSamplers());
unitsForTextures.resize(layout->GetNumSampledTextures()); unitsForTextures.resize(layout->GetNumSampledTextures());
GLuint textureUnit = layout->GetTextureUnitsUsed(); GLuint textureUnit = layout->GetTextureUnitsUsed();
for (const auto& combined : combinedSamplersSet) { for (const auto& combined : combinedSamplersSet) {
std::string name = combined.GetName(); std::string name = combined.GetName();
GLint location = glGetUniformLocation(program, name.c_str()); GLint location = glGetUniformLocation(program, name.c_str());
glUniform1i(location, textureUnit); glUniform1i(location, textureUnit);
GLuint samplerIndex = indices[combined.samplerLocation.group][combined.samplerLocation.binding]; GLuint samplerIndex = indices[combined.samplerLocation.group][combined.samplerLocation.binding];
unitsForSamplers[samplerIndex].push_back(textureUnit); unitsForSamplers[samplerIndex].push_back(textureUnit);
GLuint textureIndex = indices[combined.textureLocation.group][combined.textureLocation.binding]; GLuint textureIndex = indices[combined.textureLocation.group][combined.textureLocation.binding];
unitsForTextures[textureIndex].push_back(textureUnit); unitsForTextures[textureIndex].push_back(textureUnit);
textureUnit ++; textureUnit ++;
} }
} }
} }
const Pipeline::GLPushConstantInfo& Pipeline::GetGLPushConstants(nxt::ShaderStage stage) const { const Pipeline::GLPushConstantInfo& Pipeline::GetGLPushConstants(nxt::ShaderStage stage) const {
return glPushConstants[stage]; return glPushConstants[stage];
} }
const std::vector<GLuint>& Pipeline::GetTextureUnitsForSampler(GLuint index) const { const std::vector<GLuint>& Pipeline::GetTextureUnitsForSampler(GLuint index) const {
ASSERT(index >= 0 && index < unitsForSamplers.size()); ASSERT(index >= 0 && index < unitsForSamplers.size());
return unitsForSamplers[index]; return unitsForSamplers[index];
} }
const std::vector<GLuint>& Pipeline::GetTextureUnitsForTexture(GLuint index) const { const std::vector<GLuint>& Pipeline::GetTextureUnitsForTexture(GLuint index) const {
ASSERT(index >= 0 && index < unitsForSamplers.size()); ASSERT(index >= 0 && index < unitsForSamplers.size());
return unitsForTextures[index]; return unitsForTextures[index];
} }
GLuint Pipeline::GetProgramHandle() const { GLuint Pipeline::GetProgramHandle() const {
return program; return program;
} }
void Pipeline::ApplyNow() { void Pipeline::ApplyNow() {
glUseProgram(program); glUseProgram(program);
auto inputState = ToBackend(GetInputState()); auto inputState = ToBackend(GetInputState());
glBindVertexArray(inputState->GetVAO()); glBindVertexArray(inputState->GetVAO());
auto depthStencilState = ToBackend(GetDepthStencilState()); auto depthStencilState = ToBackend(GetDepthStencilState());
depthStencilState->ApplyNow(); depthStencilState->ApplyNow();
} }
} }
} }