Add DepthStencilState
Add depth and stencil tests. This is currently only implemented for the OpenGL API. HelloDepthStencil is a test using the depth and stencil buffers to do reflections. Currently clearing / stencil clearing is not working properly.
This commit is contained in:
parent
2711e9658d
commit
3efcf2172d
|
@ -72,4 +72,8 @@ add_executable(SpirvTest SpirvTest.cpp)
|
|||
target_link_libraries(SpirvTest shaderc spirv-cross nxtcpp)
|
||||
SetCXX14(SpirvTest)
|
||||
|
||||
add_executable(CppHelloDepthStencil HelloDepthStencil.cpp)
|
||||
target_link_libraries(CppHelloDepthStencil utils)
|
||||
SetCXX14(CppHelloDepthStencil)
|
||||
|
||||
add_subdirectory(glTFViewer)
|
||||
|
|
|
@ -0,0 +1,343 @@
|
|||
// Copyright 2017 The NXT Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
#include <vector>
|
||||
#include <glm/glm/glm.hpp>
|
||||
#include <glm/glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/glm/gtc/type_ptr.hpp>
|
||||
|
||||
nxt::Device device;
|
||||
|
||||
nxt::Buffer indexBuffer;
|
||||
nxt::Buffer vertexBuffer;
|
||||
nxt::Buffer planeBuffer;
|
||||
nxt::Buffer cameraBuffer;
|
||||
nxt::Buffer transformBuffer[2];
|
||||
|
||||
nxt::BindGroup cameraBindGroup;
|
||||
nxt::BindGroup bindGroup[2];
|
||||
nxt::BindGroup cubeTransformBindGroup[2];
|
||||
|
||||
nxt::Queue queue;
|
||||
nxt::Pipeline pipeline;
|
||||
nxt::Pipeline planePipeline;
|
||||
nxt::Pipeline reflectionPipeline;
|
||||
nxt::RenderPass renderpass;
|
||||
nxt::Framebuffer framebuffer;
|
||||
|
||||
void initBuffers() {
|
||||
static const uint32_t indexData[6*6] = {
|
||||
0, 1, 2,
|
||||
0, 2, 3,
|
||||
|
||||
4, 5, 6,
|
||||
4, 6, 7,
|
||||
|
||||
8, 9, 10,
|
||||
8, 10, 11,
|
||||
|
||||
12, 13, 14,
|
||||
12, 14, 15,
|
||||
|
||||
16, 17, 18,
|
||||
16, 18, 19,
|
||||
|
||||
20, 21, 22,
|
||||
20, 22, 23
|
||||
};
|
||||
indexBuffer = device.CreateBufferBuilder()
|
||||
.SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Index)
|
||||
.SetInitialUsage(nxt::BufferUsageBit::Mapped)
|
||||
.SetSize(sizeof(indexData))
|
||||
.GetResult();
|
||||
indexBuffer.SetSubData(0, sizeof(indexData) / sizeof(uint32_t), indexData);
|
||||
indexBuffer.FreezeUsage(nxt::BufferUsageBit::Index);
|
||||
|
||||
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, 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, 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, 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()
|
||||
.SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Vertex)
|
||||
.SetInitialUsage(nxt::BufferUsageBit::Mapped)
|
||||
.SetSize(sizeof(vertexData))
|
||||
.GetResult();
|
||||
vertexBuffer.SetSubData(0, sizeof(vertexData) / sizeof(uint32_t),
|
||||
reinterpret_cast<const uint32_t*>(vertexData));
|
||||
vertexBuffer.FreezeUsage(nxt::BufferUsageBit::Vertex);
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
planeBuffer = device.CreateBufferBuilder()
|
||||
.SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Vertex)
|
||||
.SetInitialUsage(nxt::BufferUsageBit::Mapped)
|
||||
.SetSize(sizeof(planeData))
|
||||
.GetResult();
|
||||
planeBuffer.SetSubData(0, sizeof(planeData) / sizeof(uint32_t),
|
||||
reinterpret_cast<const uint32_t*>(planeData));
|
||||
planeBuffer.FreezeUsage(nxt::BufferUsageBit::Vertex);
|
||||
}
|
||||
|
||||
struct {
|
||||
glm::mat4 view;
|
||||
glm::mat4 proj;
|
||||
} cameraData;
|
||||
|
||||
void init() {
|
||||
device = CreateCppNXTDevice();
|
||||
|
||||
queue = device.CreateQueueBuilder().GetResult();
|
||||
|
||||
initBuffers();
|
||||
|
||||
nxt::ShaderModule vsModule = CreateShaderModule(device, nxt::ShaderStage::Vertex, R"(
|
||||
#version 450
|
||||
layout(set = 0, binding = 0) uniform cameraData {
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
} camera;
|
||||
layout(set = 0, binding = 1) uniform modelData {
|
||||
mat4 modelMatrix;
|
||||
};
|
||||
layout(location = 0) in vec3 pos;
|
||||
layout(location = 1) in vec3 col;
|
||||
layout(location = 2) out vec3 f_col;
|
||||
void main() {
|
||||
f_col = col;
|
||||
gl_Position = camera.proj * camera.view * modelMatrix * vec4(pos, 1.0);
|
||||
})"
|
||||
);
|
||||
|
||||
nxt::ShaderModule fsModule = CreateShaderModule(device, nxt::ShaderStage::Fragment, R"(
|
||||
#version 450
|
||||
layout(location = 2) in vec3 f_col;
|
||||
out vec4 fragColor;
|
||||
void main() {
|
||||
fragColor = vec4(f_col, 1.0);
|
||||
})"
|
||||
);
|
||||
|
||||
auto inputState = device.CreateInputStateBuilder()
|
||||
.SetAttribute(0, 0, nxt::VertexFormat::FloatR32G32B32, 0)
|
||||
.SetAttribute(1, 0, nxt::VertexFormat::FloatR32G32B32, 3 * sizeof(float))
|
||||
.SetInput(0, 6 * sizeof(float), nxt::InputStepMode::Vertex)
|
||||
.SetInput(1, 6 * sizeof(float), nxt::InputStepMode::Vertex)
|
||||
.GetResult();
|
||||
|
||||
auto depthStencilState = device.CreateDepthStencilStateBuilder()
|
||||
.SetDepthEnabled(true)
|
||||
.GetResult();
|
||||
|
||||
nxt::BindGroupLayout bgl = device.CreateBindGroupLayoutBuilder()
|
||||
.SetBindingsType(nxt::ShaderStageBit::Vertex, nxt::BindingType::UniformBuffer, 0, 2)
|
||||
.GetResult();
|
||||
|
||||
nxt::PipelineLayout pl = device.CreatePipelineLayoutBuilder()
|
||||
.SetBindGroupLayout(0, bgl)
|
||||
.GetResult();
|
||||
|
||||
cameraBuffer = device.CreateBufferBuilder()
|
||||
.SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Uniform)
|
||||
.SetInitialUsage(nxt::BufferUsageBit::Mapped)
|
||||
.SetSize(sizeof(cameraData))
|
||||
.GetResult();
|
||||
|
||||
glm::mat4 transform(1.0);
|
||||
|
||||
transformBuffer[0] = device.CreateBufferBuilder()
|
||||
.SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Uniform)
|
||||
.SetInitialUsage(nxt::BufferUsageBit::Mapped)
|
||||
.SetSize(sizeof(glm::mat4))
|
||||
.GetResult();
|
||||
transformBuffer[0].SetSubData(0, sizeof(glm::mat4) / sizeof(uint32_t), reinterpret_cast<uint32_t*>(&transform));
|
||||
transformBuffer[0].FreezeUsage(nxt::BufferUsageBit::Uniform);
|
||||
|
||||
transform = glm::translate(transform, glm::vec3(0.f, -2.f, 0.f));
|
||||
|
||||
transformBuffer[1] = device.CreateBufferBuilder()
|
||||
.SetAllowedUsage(nxt::BufferUsageBit::Mapped | nxt::BufferUsageBit::Uniform)
|
||||
.SetInitialUsage(nxt::BufferUsageBit::Mapped)
|
||||
.SetSize(sizeof(glm::mat4))
|
||||
.GetResult();
|
||||
transformBuffer[1].SetSubData(0, sizeof(glm::mat4) / sizeof(uint32_t), reinterpret_cast<uint32_t*>(&transform));
|
||||
transformBuffer[1].FreezeUsage(nxt::BufferUsageBit::Uniform);
|
||||
|
||||
nxt::BufferView cameraBufferView = cameraBuffer.CreateBufferViewBuilder()
|
||||
.SetExtent(0, sizeof(cameraData))
|
||||
.GetResult();
|
||||
|
||||
nxt::BufferView transformBufferView[2] = {
|
||||
transformBuffer[0].CreateBufferViewBuilder()
|
||||
.SetExtent(0, sizeof(glm::mat4))
|
||||
.GetResult(),
|
||||
transformBuffer[1].CreateBufferViewBuilder()
|
||||
.SetExtent(0, sizeof(glm::mat4))
|
||||
.GetResult(),
|
||||
};
|
||||
|
||||
bindGroup[0] = device.CreateBindGroupBuilder()
|
||||
.SetLayout(bgl)
|
||||
.SetUsage(nxt::BindGroupUsage::Frozen)
|
||||
.SetBufferViews(0, 1, &cameraBufferView)
|
||||
.SetBufferViews(1, 1, &transformBufferView[0])
|
||||
.GetResult();
|
||||
|
||||
bindGroup[1] = device.CreateBindGroupBuilder()
|
||||
.SetLayout(bgl)
|
||||
.SetUsage(nxt::BindGroupUsage::Frozen)
|
||||
.SetBufferViews(0, 1, &cameraBufferView)
|
||||
.SetBufferViews(1, 1, &transformBufferView[1])
|
||||
.GetResult();
|
||||
|
||||
CreateDefaultRenderPass(device, &renderpass, &framebuffer);
|
||||
pipeline = device.CreatePipelineBuilder()
|
||||
.SetSubpass(renderpass, 0)
|
||||
.SetLayout(pl)
|
||||
.SetStage(nxt::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(nxt::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetInputState(inputState)
|
||||
.SetDepthStencilState(depthStencilState)
|
||||
.GetResult();
|
||||
|
||||
auto planeStencilState = device.CreateDepthStencilStateBuilder()
|
||||
.SetDepthEnabled(true)
|
||||
.SetDepthWrite(nxt::DepthWriteMode::Disabled)
|
||||
.SetStencilEnabled(true)
|
||||
.SetStencilReferenceMode(nxt::StencilReferenceMode::Static)
|
||||
.SetStencilReference(nxt::Face::Both, 1)
|
||||
.SetStencilCompareFunction(nxt::Face::Both, nxt::CompareFunction::Always)
|
||||
.SetStencilOperation(nxt::Face::Both, nxt::StencilOperation::Keep, nxt::StencilOperation::Keep, nxt::StencilOperation::Replace)
|
||||
.SetStencilMask(nxt::Face::Both, 0xff, 0xff)
|
||||
.GetResult();
|
||||
|
||||
planePipeline = device.CreatePipelineBuilder()
|
||||
.SetSubpass(renderpass, 0)
|
||||
.SetLayout(pl)
|
||||
.SetStage(nxt::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(nxt::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetInputState(inputState)
|
||||
.SetDepthStencilState(planeStencilState)
|
||||
.GetResult();
|
||||
|
||||
auto reflectionStencilState = device.CreateDepthStencilStateBuilder()
|
||||
.SetDepthEnabled(true)
|
||||
.SetDepthWrite(nxt::DepthWriteMode::Enabled)
|
||||
.SetStencilEnabled(true)
|
||||
.SetStencilReferenceMode(nxt::StencilReferenceMode::Static)
|
||||
.SetStencilReference(nxt::Face::Both, 1)
|
||||
.SetStencilCompareFunction(nxt::Face::Both, nxt::CompareFunction::Equal)
|
||||
.SetStencilOperation(nxt::Face::Both, nxt::StencilOperation::Keep, nxt::StencilOperation::Keep, nxt::StencilOperation::Replace)
|
||||
.SetStencilMask(nxt::Face::Both, 0xff, 0x00)
|
||||
.GetResult();
|
||||
|
||||
reflectionPipeline = device.CreatePipelineBuilder()
|
||||
.SetSubpass(renderpass, 0)
|
||||
.SetLayout(pl)
|
||||
.SetStage(nxt::ShaderStage::Vertex, vsModule, "main")
|
||||
.SetStage(nxt::ShaderStage::Fragment, fsModule, "main")
|
||||
.SetInputState(inputState)
|
||||
.SetDepthStencilState(reflectionStencilState)
|
||||
.GetResult();
|
||||
|
||||
cameraData.proj = glm::perspective(glm::radians(45.0f), 1.f, 1.0f, 100.0f);
|
||||
}
|
||||
|
||||
struct {uint32_t a; float b;} s;
|
||||
void frame() {
|
||||
s.a = (s.a + 1) % 256;
|
||||
s.b += 0.01;
|
||||
if (s.b >= 1.0f) {s.b = 0.0f;}
|
||||
static const uint32_t vertexBufferOffsets[1] = {0};
|
||||
|
||||
cameraData.view = glm::lookAt(
|
||||
glm::vec3(10.f * std::sin(glm::radians(s.b * 360.f)), 2.f, 10.f * std::cos(glm::radians(s.b * 360.f))),
|
||||
glm::vec3(0.0f, -1.0f, 0.0f),
|
||||
glm::vec3(0.0f, 1.0f, 0.0f)
|
||||
);
|
||||
|
||||
cameraBuffer.TransitionUsage(nxt::BufferUsageBit::Mapped);
|
||||
cameraBuffer.SetSubData(0, sizeof(cameraData) / sizeof(uint32_t), reinterpret_cast<uint32_t*>(&cameraData));
|
||||
|
||||
nxt::CommandBuffer commands = device.CreateCommandBufferBuilder()
|
||||
.BeginRenderPass(renderpass, framebuffer)
|
||||
.SetPipeline(pipeline)
|
||||
.TransitionBufferUsage(cameraBuffer, nxt::BufferUsageBit::Uniform)
|
||||
.SetBindGroup(0, bindGroup[0])
|
||||
.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets)
|
||||
.SetIndexBuffer(indexBuffer, 0, nxt::IndexFormat::Uint32)
|
||||
.DrawElements(36, 1, 0, 0)
|
||||
|
||||
.SetPipeline(planePipeline)
|
||||
.SetVertexBuffers(0, 1, &planeBuffer, vertexBufferOffsets)
|
||||
.DrawElements(6, 1, 0, 0)
|
||||
|
||||
.SetPipeline(reflectionPipeline)
|
||||
.SetVertexBuffers(0, 1, &vertexBuffer, vertexBufferOffsets)
|
||||
.SetBindGroup(0, bindGroup[1])
|
||||
.DrawElements(36, 1, 0, 0)
|
||||
.EndRenderPass()
|
||||
.GetResult();
|
||||
|
||||
queue.Submit(1, &commands);
|
||||
DoSwapBuffers();
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
if (!InitUtils(argc, argv)) {
|
||||
return 1;
|
||||
}
|
||||
init();
|
||||
|
||||
while (!ShouldQuit()) {
|
||||
frame();
|
||||
USleep(16000);
|
||||
}
|
||||
|
||||
// TODO release stuff
|
||||
}
|
137
next.json
137
next.json
|
@ -341,6 +341,19 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"compare function": {
|
||||
"category": "enum",
|
||||
"values": [
|
||||
{"value": 0, "name": "never"},
|
||||
{"value": 1, "name": "less"},
|
||||
{"value": 2, "name": "less equal"},
|
||||
{"value": 3, "name": "greater"},
|
||||
{"value": 4, "name": "greater equal"},
|
||||
{"value": 5, "name": "equal"},
|
||||
{"value": 6, "name": "not equal"},
|
||||
{"value": 7, "name": "always"}
|
||||
]
|
||||
},
|
||||
"device": {
|
||||
"category": "object",
|
||||
"methods": [
|
||||
|
@ -360,6 +373,10 @@
|
|||
"name": "create command buffer builder",
|
||||
"returns": "command buffer builder"
|
||||
},
|
||||
{
|
||||
"name": "create depth stencil state builder",
|
||||
"returns": "depth stencil state builder"
|
||||
},
|
||||
{
|
||||
"name": "create framebuffer builder",
|
||||
"returns": "framebuffer builder"
|
||||
|
@ -414,9 +431,97 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"depth stencil state": {
|
||||
"category": "object"
|
||||
},
|
||||
"depth stencil state builder": {
|
||||
"category": "object",
|
||||
"methods": [
|
||||
{
|
||||
"name": "get result",
|
||||
"returns": "depth stencil state"
|
||||
},
|
||||
{
|
||||
"name": "set depth enabled",
|
||||
"args": [
|
||||
{"name": "depth enabled", "type": "bool"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "set depth compare function",
|
||||
"args": [
|
||||
{"name": "depth compare function", "type": "compare function"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "set depth write",
|
||||
"args" : [
|
||||
{"name": "depth write mode", "type": "depth write mode"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "set stencil enabled",
|
||||
"args": [
|
||||
{"name": "stencil enabled", "type": "bool"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "set stencil reference mode",
|
||||
"args": [
|
||||
{"name": "reference mode", "type": "stencil reference mode"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "set stencil operation",
|
||||
"args": [
|
||||
{"name": "face", "type": "face"},
|
||||
{"name": "stencil failure operation", "type": "stencil operation"},
|
||||
{"name": "depth failure operation", "type": "stencil operation"},
|
||||
{"name": "stencil pass operation", "type": "stencil operation"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "set stencil compare function",
|
||||
"args": [
|
||||
{"name": "face", "type": "face"},
|
||||
{"name": "stencil compare function", "type": "compare function"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "set stencil mask",
|
||||
"args": [
|
||||
{"name": "face", "type": "face"},
|
||||
{"name": "read mask", "type": "uint32_t"},
|
||||
{"name": "write mask", "type": "uint32_t"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "set stencil reference",
|
||||
"args": [
|
||||
{"name": "face", "type": "face"},
|
||||
{"name": "reference", "type": "int"}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"depth write mode": {
|
||||
"category": "enum",
|
||||
"values": [
|
||||
{"value": 0, "name": "disabled"},
|
||||
{"value": 1, "name": "enabled"}
|
||||
]
|
||||
},
|
||||
"device error callback": {
|
||||
"category": "natively defined"
|
||||
},
|
||||
"face": {
|
||||
"category": "bitmask",
|
||||
"values": [
|
||||
{"value": 1, "name": "back"},
|
||||
{"value": 2, "name": "front"},
|
||||
{"value": 3, "name": "both"}
|
||||
]
|
||||
},
|
||||
"filter mode": {
|
||||
"category": "enum",
|
||||
"values": [
|
||||
|
@ -535,6 +640,12 @@
|
|||
"args": [
|
||||
{"name": "input", "type": "input state"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "set depth stencil state",
|
||||
"args": [
|
||||
{"name": "input", "type": "depth stencil state"}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -677,6 +788,26 @@
|
|||
{"value": 4, "name": "compute"}
|
||||
]
|
||||
},
|
||||
"stencil reference mode": {
|
||||
"category": "enum",
|
||||
"values": [
|
||||
{"value": 0, "name": "static"},
|
||||
{"value": 1, "name": "dynamic"}
|
||||
]
|
||||
},
|
||||
"stencil operation": {
|
||||
"category": "enum",
|
||||
"values": [
|
||||
{"value": 0, "name": "keep"},
|
||||
{"value": 1, "name": "zero"},
|
||||
{"value": 2, "name": "replace"},
|
||||
{"value": 3, "name": "invert"},
|
||||
{"value": 4, "name": "increment clamp"},
|
||||
{"value": 5, "name": "decrement clamp"},
|
||||
{"value": 6, "name": "increment wrap"},
|
||||
{"value": 7, "name": "decrement wrap"}
|
||||
]
|
||||
},
|
||||
"texture": {
|
||||
"category": "object",
|
||||
"methods": [
|
||||
|
@ -794,5 +925,11 @@
|
|||
},
|
||||
"uint32_t": {
|
||||
"category": "native"
|
||||
},
|
||||
"bool": {
|
||||
"category": "native"
|
||||
},
|
||||
"int": {
|
||||
"category": "native"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ list(APPEND BACKEND_SOURCES
|
|||
${COMMON_DIR}/CommandAllocator.h
|
||||
${COMMON_DIR}/CommandBuffer.cpp
|
||||
${COMMON_DIR}/CommandBuffer.h
|
||||
${COMMON_DIR}/DepthStencilState.cpp
|
||||
${COMMON_DIR}/DepthStencilState.h
|
||||
${COMMON_DIR}/Device.cpp
|
||||
${COMMON_DIR}/Device.h
|
||||
${COMMON_DIR}/Forward.h
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
// Copyright 2017 The NXT Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "DepthStencilState.h"
|
||||
|
||||
#include "Device.h"
|
||||
|
||||
namespace backend {
|
||||
|
||||
// DepthStencilStateBase
|
||||
|
||||
DepthStencilStateBase::DepthStencilStateBase(DepthStencilStateBuilder* builder)
|
||||
: depthEnabled(builder->depthEnabled), stencilEnabled(builder->stencilEnabled),
|
||||
depthInfo(builder->depthInfo),
|
||||
stencilInfos { builder->stencilInfos[0], builder->stencilInfos[1] } {
|
||||
}
|
||||
|
||||
bool DepthStencilStateBase::DepthIsEnabled() const {
|
||||
return depthEnabled;
|
||||
}
|
||||
|
||||
bool DepthStencilStateBase::StencilIsEnabled() const {
|
||||
return stencilEnabled;
|
||||
}
|
||||
|
||||
nxt::StencilReferenceMode DepthStencilStateBase::GetStencilReferenceMode() const {
|
||||
return referenceMode;
|
||||
}
|
||||
|
||||
const DepthStencilStateBase::DepthInfo& DepthStencilStateBase::GetDepth() const {
|
||||
return depthInfo;
|
||||
}
|
||||
|
||||
const DepthStencilStateBase::StencilInfo& DepthStencilStateBase::GetStencil(nxt::Face face) const {
|
||||
switch (face) {
|
||||
case nxt::Face::Back:
|
||||
return stencilInfos[0];
|
||||
case nxt::Face::Front:
|
||||
return stencilInfos[1];
|
||||
default:
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// DepthStencilStateBuilder
|
||||
|
||||
DepthStencilStateBuilder::DepthStencilStateBuilder(DeviceBase* device) : Builder(device) {
|
||||
}
|
||||
|
||||
DepthStencilStateBase* DepthStencilStateBuilder::GetResultImpl() {
|
||||
return device->CreateDepthStencilState(this);
|
||||
}
|
||||
|
||||
void DepthStencilStateBuilder::SetDepthEnabled(bool depthEnabled) {
|
||||
this->depthEnabled = depthEnabled;
|
||||
}
|
||||
|
||||
void DepthStencilStateBuilder::SetDepthCompareFunction(nxt::CompareFunction depthCompareFunction) {
|
||||
depthInfo.compareFunction = depthCompareFunction;
|
||||
}
|
||||
|
||||
void DepthStencilStateBuilder::SetDepthWrite(nxt::DepthWriteMode depthWriteMode) {
|
||||
depthInfo.depthWriteMode = depthWriteMode;
|
||||
}
|
||||
|
||||
void DepthStencilStateBuilder::SetStencilEnabled(bool stencilEnabled) {
|
||||
this->stencilEnabled = stencilEnabled;
|
||||
}
|
||||
|
||||
void DepthStencilStateBuilder::SetStencilReferenceMode(nxt::StencilReferenceMode referenceMode) {
|
||||
this->referenceMode = referenceMode;
|
||||
}
|
||||
|
||||
void DepthStencilStateBuilder::SetStencilOperation(nxt::Face face, nxt::StencilOperation stencilFail,
|
||||
nxt::StencilOperation depthFail, nxt::StencilOperation stencilPass) {
|
||||
if (face & nxt::Face::Back) {
|
||||
auto& stencilInfo = stencilInfos[0];
|
||||
stencilInfo.stencilFail = stencilFail;
|
||||
stencilInfo.depthFail = stencilFail;
|
||||
stencilInfo.stencilPass = stencilPass;
|
||||
}
|
||||
if (face & nxt::Face::Front) {
|
||||
auto& stencilInfo = stencilInfos[1];
|
||||
stencilInfo.stencilFail = stencilFail;
|
||||
stencilInfo.depthFail = stencilFail;
|
||||
stencilInfo.stencilPass = stencilPass;
|
||||
}
|
||||
}
|
||||
|
||||
void DepthStencilStateBuilder::SetStencilCompareFunction(nxt::Face face, nxt::CompareFunction stencilCompareFunction) {
|
||||
if (face & nxt::Face::Back) {
|
||||
auto& stencilInfo = stencilInfos[0];
|
||||
stencilInfo.compareFunction = stencilCompareFunction;
|
||||
}
|
||||
if (face & nxt::Face::Front) {
|
||||
auto& stencilInfo = stencilInfos[1];
|
||||
stencilInfo.compareFunction = stencilCompareFunction;
|
||||
}
|
||||
}
|
||||
|
||||
void DepthStencilStateBuilder::SetStencilMask(nxt::Face face, uint32_t readMask, uint32_t writeMask) {
|
||||
if (face & nxt::Face::Back) {
|
||||
auto& stencilInfo = stencilInfos[0];
|
||||
stencilInfo.readMask = readMask;
|
||||
stencilInfo.writeMask = writeMask;
|
||||
}
|
||||
if (face & nxt::Face::Front) {
|
||||
auto& stencilInfo = stencilInfos[1];
|
||||
stencilInfo.readMask = readMask;
|
||||
stencilInfo.writeMask = writeMask;
|
||||
}
|
||||
}
|
||||
|
||||
void DepthStencilStateBuilder::SetStencilReference(nxt::Face face, int reference) {
|
||||
if (face & nxt::Face::Back) {
|
||||
auto& stencilInfo = stencilInfos[0];
|
||||
stencilInfo.reference = reference;
|
||||
}
|
||||
if (face & nxt::Face::Front) {
|
||||
auto& stencilInfo = stencilInfos[1];
|
||||
stencilInfo.reference = reference;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
// Copyright 2017 The NXT Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef BACKEND_COMMON_DEPTHSTENCILSTATE_H_
|
||||
#define BACKEND_COMMON_DEPTHSTENCILSTATE_H_
|
||||
|
||||
#include "Forward.h"
|
||||
#include "Builder.h"
|
||||
#include "RefCounted.h"
|
||||
|
||||
#include "nxt/nxtcpp.h"
|
||||
|
||||
namespace backend {
|
||||
|
||||
|
||||
class DepthStencilStateBase : public RefCounted {
|
||||
public:
|
||||
DepthStencilStateBase(DepthStencilStateBuilder* builder);
|
||||
|
||||
struct DepthInfo {
|
||||
nxt::CompareFunction compareFunction = nxt::CompareFunction::Less;
|
||||
nxt::DepthWriteMode depthWriteMode = nxt::DepthWriteMode::Enabled;
|
||||
};
|
||||
|
||||
struct StencilInfo {
|
||||
nxt::CompareFunction compareFunction = nxt::CompareFunction::Always;
|
||||
nxt::StencilOperation stencilFail = nxt::StencilOperation::Keep;
|
||||
nxt::StencilOperation depthFail = nxt::StencilOperation::Keep;
|
||||
nxt::StencilOperation stencilPass = nxt::StencilOperation::Keep;
|
||||
uint32_t readMask = 0xff;
|
||||
uint32_t writeMask = 0xff;
|
||||
int reference = 0;
|
||||
};
|
||||
|
||||
bool DepthIsEnabled() const;
|
||||
bool StencilIsEnabled() const;
|
||||
nxt::StencilReferenceMode GetStencilReferenceMode() const;
|
||||
const DepthInfo& GetDepth() const;
|
||||
const StencilInfo& GetStencil(nxt::Face face) const;
|
||||
|
||||
private:
|
||||
bool depthEnabled = false;
|
||||
bool stencilEnabled = false;
|
||||
nxt::StencilReferenceMode referenceMode = nxt::StencilReferenceMode::Static;
|
||||
DepthInfo depthInfo;
|
||||
StencilInfo stencilInfos[2];
|
||||
};
|
||||
|
||||
class DepthStencilStateBuilder : public Builder<DepthStencilStateBase> {
|
||||
public:
|
||||
DepthStencilStateBuilder(DeviceBase* device);
|
||||
|
||||
// NXT API
|
||||
void SetDepthEnabled(bool depthEnabled);
|
||||
void SetDepthCompareFunction(nxt::CompareFunction depthCompareFunction);
|
||||
void SetDepthWrite(nxt::DepthWriteMode depthWriteMode);
|
||||
void SetStencilEnabled(bool stencilEnabled);
|
||||
void SetStencilReferenceMode(nxt::StencilReferenceMode referenceMode);
|
||||
void SetStencilOperation(nxt::Face face, nxt::StencilOperation stencilFail,
|
||||
nxt::StencilOperation depthFail, nxt::StencilOperation stencilPass);
|
||||
void SetStencilCompareFunction(nxt::Face face, nxt::CompareFunction stencilCompareFunction);
|
||||
void SetStencilMask(nxt::Face face, uint32_t readMask, uint32_t writeMask);
|
||||
void SetStencilReference(nxt::Face face, int reference);
|
||||
|
||||
private:
|
||||
friend class DepthStencilStateBase;
|
||||
|
||||
DepthStencilStateBase* GetResultImpl() override;
|
||||
|
||||
bool depthEnabled;
|
||||
bool stencilEnabled;
|
||||
nxt::StencilReferenceMode referenceMode;
|
||||
DepthStencilStateBase::DepthInfo depthInfo;
|
||||
DepthStencilStateBase::StencilInfo stencilInfos[2];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // BACKEND_COMMON_DEPTHSTENCILSTATE_H_
|
|
@ -18,6 +18,7 @@
|
|||
#include "BindGroupLayout.h"
|
||||
#include "Buffer.h"
|
||||
#include "CommandBuffer.h"
|
||||
#include "DepthStencilState.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "InputState.h"
|
||||
#include "Pipeline.h"
|
||||
|
@ -98,6 +99,9 @@ namespace backend {
|
|||
CommandBufferBuilder* DeviceBase::CreateCommandBufferBuilder() {
|
||||
return new CommandBufferBuilder(this);
|
||||
}
|
||||
DepthStencilStateBuilder* DeviceBase::CreateDepthStencilStateBuilder() {
|
||||
return new DepthStencilStateBuilder(this);
|
||||
}
|
||||
FramebufferBuilder* DeviceBase::CreateFramebufferBuilder() {
|
||||
return new FramebufferBuilder(this);
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ namespace backend {
|
|||
virtual BufferBase* CreateBuffer(BufferBuilder* builder) = 0;
|
||||
virtual BufferViewBase* CreateBufferView(BufferViewBuilder* builder) = 0;
|
||||
virtual CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) = 0;
|
||||
virtual DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) = 0;
|
||||
virtual FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) = 0;
|
||||
virtual InputStateBase* CreateInputState(InputStateBuilder* builder) = 0;
|
||||
virtual PipelineBase* CreatePipeline(PipelineBuilder* builder) = 0;
|
||||
|
@ -74,6 +75,7 @@ namespace backend {
|
|||
BufferBuilder* CreateBufferBuilder();
|
||||
BufferViewBuilder* CreateBufferViewBuilder();
|
||||
CommandBufferBuilder* CreateCommandBufferBuilder();
|
||||
DepthStencilStateBuilder* CreateDepthStencilStateBuilder();
|
||||
FramebufferBuilder* CreateFramebufferBuilder();
|
||||
InputStateBuilder* CreateInputStateBuilder();
|
||||
PipelineBuilder* CreatePipelineBuilder();
|
||||
|
|
|
@ -32,6 +32,8 @@ namespace backend {
|
|||
class BufferViewBuilder;
|
||||
class CommandBufferBase;
|
||||
class CommandBufferBuilder;
|
||||
class DepthStencilStateBase;
|
||||
class DepthStencilStateBuilder;
|
||||
class FramebufferBase;
|
||||
class FramebufferBuilder;
|
||||
class InputStateBase;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "Pipeline.h"
|
||||
|
||||
#include "Device.h"
|
||||
#include "DepthStencilState.h"
|
||||
#include "InputState.h"
|
||||
#include "PipelineLayout.h"
|
||||
#include "RenderPass.h"
|
||||
|
@ -27,7 +28,7 @@ namespace backend {
|
|||
PipelineBase::PipelineBase(PipelineBuilder* builder)
|
||||
: device(builder->device), stageMask(builder->stageMask), layout(std::move(builder->layout)),
|
||||
renderPass(std::move(builder->renderPass)), subpass(builder->subpass),
|
||||
inputState(std::move(builder->inputState)) {
|
||||
inputState(std::move(builder->inputState)), depthStencilState(std::move(builder->depthStencilState)) {
|
||||
|
||||
if (stageMask != (nxt::ShaderStageBit::Vertex | nxt::ShaderStageBit::Fragment) &&
|
||||
stageMask != nxt::ShaderStageBit::Compute) {
|
||||
|
@ -95,6 +96,10 @@ namespace backend {
|
|||
return inputState.Get();
|
||||
}
|
||||
|
||||
DepthStencilStateBase* PipelineBase::GetDepthStencilState() {
|
||||
return depthStencilState.Get();
|
||||
}
|
||||
|
||||
bool PipelineBase::IsCompute() const {
|
||||
return stageMask == nxt::ShaderStageBit::Compute;
|
||||
}
|
||||
|
@ -118,6 +123,9 @@ namespace backend {
|
|||
if (!inputState) {
|
||||
inputState = device->CreateInputStateBuilder()->GetResult();
|
||||
}
|
||||
if (!depthStencilState) {
|
||||
depthStencilState = device->CreateDepthStencilStateBuilder()->GetResult();
|
||||
}
|
||||
|
||||
return device->CreatePipeline(this);
|
||||
}
|
||||
|
@ -157,5 +165,9 @@ namespace backend {
|
|||
this->inputState = inputState;
|
||||
}
|
||||
|
||||
void PipelineBuilder::SetDepthStencilState(DepthStencilStateBase* depthStencilState) {
|
||||
this->depthStencilState = depthStencilState;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ namespace backend {
|
|||
PipelineLayoutBase* GetLayout();
|
||||
RenderPassBase* GetRenderPass();
|
||||
InputStateBase* GetInputState();
|
||||
DepthStencilStateBase* GetDepthStencilState();
|
||||
|
||||
// TODO(cwallez@chromium.org): split compute and render pipelines
|
||||
bool IsCompute() const;
|
||||
|
@ -60,6 +61,7 @@ namespace backend {
|
|||
uint32_t subpass;
|
||||
PerStage<PushConstantInfo> pushConstants;
|
||||
Ref<InputStateBase> inputState;
|
||||
Ref<DepthStencilStateBase> depthStencilState;
|
||||
};
|
||||
|
||||
class PipelineBuilder : public Builder<PipelineBase> {
|
||||
|
@ -77,6 +79,7 @@ namespace backend {
|
|||
void SetSubpass(RenderPassBase* renderPass, uint32_t subpass);
|
||||
void SetStage(nxt::ShaderStage stage, ShaderModuleBase* module, const char* entryPoint);
|
||||
void SetInputState(InputStateBase* inputState);
|
||||
void SetDepthStencilState(DepthStencilStateBase* depthStencilState);
|
||||
|
||||
private:
|
||||
friend class PipelineBase;
|
||||
|
@ -89,6 +92,7 @@ namespace backend {
|
|||
nxt::ShaderStageBit stageMask;
|
||||
PerStage<StageInfo> stages;
|
||||
Ref<InputStateBase> inputState;
|
||||
Ref<DepthStencilStateBase> depthStencilState;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -48,6 +48,11 @@ namespace backend {
|
|||
using BackendType = typename BackendTraits::CommandBufferType;
|
||||
};
|
||||
|
||||
template<typename BackendTraits>
|
||||
struct ToBackendTraits<DepthStencilStateBase, BackendTraits> {
|
||||
using BackendType = typename BackendTraits::DepthStencilStateType;
|
||||
};
|
||||
|
||||
template<typename BackendTraits>
|
||||
struct ToBackendTraits<FramebufferBase, BackendTraits> {
|
||||
using BackendType = typename BackendTraits::FramebufferType;
|
||||
|
|
|
@ -50,6 +50,9 @@ namespace null {
|
|||
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
|
||||
return new CommandBufferBase(builder);
|
||||
}
|
||||
DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) {
|
||||
return new DepthStencilStateBase(builder);
|
||||
}
|
||||
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
||||
return new InputStateBase(builder);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "common/BindGroupLayout.h"
|
||||
#include "common/Device.h"
|
||||
#include "common/CommandBuffer.h"
|
||||
#include "common/DepthStencilState.h"
|
||||
#include "common/InputState.h"
|
||||
#include "common/Framebuffer.h"
|
||||
#include "common/Pipeline.h"
|
||||
|
@ -41,6 +42,7 @@ namespace null {
|
|||
class Buffer;
|
||||
using BufferView = BufferViewBase;
|
||||
using CommandBuffer = CommandBufferBase;
|
||||
using DepthStencilState = DepthStencilStateBase;
|
||||
using InputState = InputStateBase;
|
||||
using Framebuffer = FramebufferBase;
|
||||
using Pipeline = PipelineBase;
|
||||
|
@ -58,6 +60,7 @@ namespace null {
|
|||
using BufferType = Buffer;
|
||||
using BufferViewType = BufferView;
|
||||
using CommandBufferType = CommandBuffer;
|
||||
using DepthStencilStateType = DepthStencilState;
|
||||
using InputStateType = InputState;
|
||||
using FramebufferType = Framebuffer;
|
||||
using PipelineType = Pipeline;
|
||||
|
@ -85,6 +88,7 @@ namespace null {
|
|||
BufferBase* CreateBuffer(BufferBuilder* builder) override;
|
||||
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
|
||||
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
||||
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
|
||||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||
FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override;
|
||||
PipelineBase* CreatePipeline(PipelineBuilder* builder) override;
|
||||
|
|
|
@ -29,6 +29,8 @@ namespace opengl {
|
|||
void HACKCLEAR() {
|
||||
glClearColor(0, 0, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClearStencil(0);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void Init(void* (*getProc)(const char*), nxtProcTable* procs, nxtDevice* device) {
|
||||
|
@ -43,6 +45,52 @@ namespace opengl {
|
|||
*device = reinterpret_cast<nxtDevice>(new Device);
|
||||
}
|
||||
|
||||
static GLuint OpenGLCompareFunction(nxt::CompareFunction compareFunction) {
|
||||
switch (compareFunction) {
|
||||
case nxt::CompareFunction::Never:
|
||||
return GL_NEVER;
|
||||
case nxt::CompareFunction::Less:
|
||||
return GL_LESS;
|
||||
case nxt::CompareFunction::LessEqual:
|
||||
return GL_LEQUAL;
|
||||
case nxt::CompareFunction::Greater:
|
||||
return GL_GREATER;
|
||||
case nxt::CompareFunction::GreaterEqual:
|
||||
return GL_GEQUAL;
|
||||
case nxt::CompareFunction::NotEqual:
|
||||
return GL_NOTEQUAL;
|
||||
case nxt::CompareFunction::Equal:
|
||||
return GL_EQUAL;
|
||||
case nxt::CompareFunction::Always:
|
||||
return GL_ALWAYS;
|
||||
default:
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
static GLuint OpenGLStencilOperation(nxt::StencilOperation stencilOperation) {
|
||||
switch (stencilOperation) {
|
||||
case nxt::StencilOperation::Keep:
|
||||
return GL_KEEP;
|
||||
case nxt::StencilOperation::Zero:
|
||||
return GL_ZERO;
|
||||
case nxt::StencilOperation::Replace:
|
||||
return GL_REPLACE;
|
||||
case nxt::StencilOperation::Invert:
|
||||
return GL_INVERT;
|
||||
case nxt::StencilOperation::IncrementClamp:
|
||||
return GL_INCR;
|
||||
case nxt::StencilOperation::DecrementClamp:
|
||||
return GL_DECR;
|
||||
case nxt::StencilOperation::IncrementWrap:
|
||||
return GL_INCR_WRAP;
|
||||
case nxt::StencilOperation::DecrementWrap:
|
||||
return GL_DECR_WRAP;
|
||||
default:
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Device
|
||||
|
||||
BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
|
||||
|
@ -60,6 +108,9 @@ namespace opengl {
|
|||
CommandBufferBase* Device::CreateCommandBuffer(CommandBufferBuilder* builder) {
|
||||
return new CommandBuffer(this, builder);
|
||||
}
|
||||
DepthStencilStateBase* Device::CreateDepthStencilState(DepthStencilStateBuilder* builder) {
|
||||
return new DepthStencilState(this, builder);
|
||||
}
|
||||
InputStateBase* Device::CreateInputState(InputStateBuilder* builder) {
|
||||
return new InputState(this, builder);
|
||||
}
|
||||
|
@ -133,6 +184,56 @@ namespace opengl {
|
|||
: BufferViewBase(builder), device(device) {
|
||||
}
|
||||
|
||||
DepthStencilState::DepthStencilState(Device* device, DepthStencilStateBuilder* builder)
|
||||
: DepthStencilStateBase(builder), device(device) {
|
||||
|
||||
}
|
||||
|
||||
void DepthStencilState::Apply() {
|
||||
if (DepthIsEnabled()) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
auto& depth = GetDepth();
|
||||
glDepthFunc(OpenGLCompareFunction(depth.compareFunction));
|
||||
switch (depth.depthWriteMode) {
|
||||
case nxt::DepthWriteMode::Disabled:
|
||||
glDepthMask(GL_FALSE);
|
||||
break;
|
||||
case nxt::DepthWriteMode::Enabled:
|
||||
glDepthMask(GL_TRUE);
|
||||
break;
|
||||
default:
|
||||
ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
static const GLuint GL_FACES[2] = { GL_BACK, GL_FRONT };
|
||||
static const nxt::Face NXT_FACES[2] = { nxt::Face::Back, nxt::Face::Front };
|
||||
if (StencilIsEnabled()) {
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
for (uint32_t i = 0; i < 2; ++i) {
|
||||
auto& stencil = GetStencil(NXT_FACES[i]);
|
||||
glStencilFuncSeparate(GL_FACES[i],
|
||||
OpenGLCompareFunction(stencil.compareFunction),
|
||||
stencil.reference,
|
||||
stencil.readMask
|
||||
);
|
||||
glStencilOpSeparate(GL_FACES[i],
|
||||
OpenGLStencilOperation(stencil.stencilFail),
|
||||
OpenGLStencilOperation(stencil.depthFail),
|
||||
OpenGLStencilOperation(stencil.stencilPass)
|
||||
);
|
||||
glStencilMaskSeparate(GL_FACES[i], stencil.writeMask);
|
||||
}
|
||||
}
|
||||
else {
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
// InputState
|
||||
|
||||
InputState::InputState(Device* device, InputStateBuilder* builder)
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "common/BindGroup.h"
|
||||
#include "common/BindGroupLayout.h"
|
||||
#include "common/Device.h"
|
||||
#include "common/DepthStencilState.h"
|
||||
#include "common/Framebuffer.h"
|
||||
#include "common/InputState.h"
|
||||
#include "common/Queue.h"
|
||||
|
@ -37,6 +38,7 @@ namespace opengl {
|
|||
class Buffer;
|
||||
class BufferView;
|
||||
class CommandBuffer;
|
||||
class DepthStencilState;
|
||||
class InputState;
|
||||
class Pipeline;
|
||||
class PipelineLayout;
|
||||
|
@ -54,6 +56,7 @@ namespace opengl {
|
|||
using BufferType = Buffer;
|
||||
using BufferViewType = BufferView;
|
||||
using CommandBufferType = CommandBuffer;
|
||||
using DepthStencilStateType = DepthStencilState;
|
||||
using InputStateType = InputState;
|
||||
using PipelineType = Pipeline;
|
||||
using PipelineLayoutType = PipelineLayout;
|
||||
|
@ -79,6 +82,7 @@ namespace opengl {
|
|||
BufferBase* CreateBuffer(BufferBuilder* builder) override;
|
||||
BufferViewBase* CreateBufferView(BufferViewBuilder* builder) override;
|
||||
CommandBufferBase* CreateCommandBuffer(CommandBufferBuilder* builder) override;
|
||||
DepthStencilStateBase* CreateDepthStencilState(DepthStencilStateBuilder* builder) override;
|
||||
InputStateBase* CreateInputState(InputStateBuilder* builder) override;
|
||||
FramebufferBase* CreateFramebuffer(FramebufferBuilder* builder) override;
|
||||
PipelineBase* CreatePipeline(PipelineBuilder* builder) override;
|
||||
|
@ -132,6 +136,15 @@ namespace opengl {
|
|||
Device* device;
|
||||
};
|
||||
|
||||
class DepthStencilState : public DepthStencilStateBase {
|
||||
public:
|
||||
DepthStencilState(Device* device, DepthStencilStateBuilder* builder);
|
||||
void Apply();
|
||||
|
||||
private:
|
||||
Device* device;
|
||||
};
|
||||
|
||||
class Framebuffer : public FramebufferBase {
|
||||
public:
|
||||
Framebuffer(Device* device, FramebufferBuilder* builder);
|
||||
|
|
|
@ -207,6 +207,8 @@ namespace opengl {
|
|||
|
||||
auto inputState = ToBackend(GetInputState());
|
||||
glBindVertexArray(inputState->GetVAO());
|
||||
auto depthStencilState = ToBackend(GetDepthStencilState());
|
||||
depthStencilState->Apply();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue