Swap chains, part 1 (#87)

Adds the swap chain interfaces to the API without changing the behavior
of anything else. This includes the C APIs for applications to provide
swap chain implementations. Also adds stub implementations on every
backend.
This commit is contained in:
Kai Ninomiya 2017-07-19 15:41:17 -07:00 committed by GitHub
parent 1e66ab93fe
commit 35bf424035
34 changed files with 645 additions and 11 deletions

View File

@ -876,6 +876,44 @@
{"value": 7, "name": "decrement wrap"}
]
},
"swap chain": {
"category": "object",
"methods": [
{
"name": "configure",
"args": [
{"name": "format", "type": "texture format"},
{"name": "width", "type": "uint32_t"},
{"name": "height", "type": "uint32_t"}
]
},
{
"name": "get next texture",
"returns": "texture"
},
{
"name": "present",
"args": [
{"name": "texture", "type": "texture"}
]
}
]
},
"swap chain builder": {
"category": "object",
"methods": [
{
"name": "get result",
"returns": "swap chain"
},
{
"name": "set implementation",
"args": [
{"name": "implementation", "type": "uint64_t"}
]
}
]
},
"texture": {
"category": "object",
"methods": [
@ -958,7 +996,8 @@
{"value": 2, "name": "transfer dst"},
{"value": 4, "name": "sampled"},
{"value": 8, "name": "storage"},
{"value": 16, "name": "output attachment"}
{"value": 16, "name": "output attachment"},
{"value": 32, "name": "present"}
]
},
"texture view": {
@ -994,5 +1033,8 @@
},
"uint32_t": {
"category": "native"
},
"uint64_t": {
"category": "native"
}
}

View File

@ -60,6 +60,8 @@ if (NXT_ENABLE_OPENGL)
${OPENGL_DIR}/SamplerGL.h
${OPENGL_DIR}/ShaderModuleGL.cpp
${OPENGL_DIR}/ShaderModuleGL.h
${OPENGL_DIR}/SwapChainGL.cpp
${OPENGL_DIR}/SwapChainGL.h
${OPENGL_DIR}/TextureGL.cpp
${OPENGL_DIR}/TextureGL.h
)
@ -130,6 +132,8 @@ if (NXT_ENABLE_METAL)
${METAL_DIR}/SamplerMTL.h
${METAL_DIR}/ShaderModuleMTL.mm
${METAL_DIR}/ShaderModuleMTL.h
${METAL_DIR}/SwapChainMTL.mm
${METAL_DIR}/SwapChainMTL.h
${METAL_DIR}/TextureMTL.mm
${METAL_DIR}/TextureMTL.h
)
@ -239,6 +243,8 @@ if (NXT_ENABLE_D3D12)
${D3D12_DIR}/SamplerD3D12.h
${D3D12_DIR}/ShaderModuleD3D12.cpp
${D3D12_DIR}/ShaderModuleD3D12.h
${D3D12_DIR}/SwapChainD3D12.cpp
${D3D12_DIR}/SwapChainD3D12.h
${D3D12_DIR}/TextureD3D12.cpp
${D3D12_DIR}/TextureD3D12.h
)
@ -292,6 +298,8 @@ list(APPEND BACKEND_SOURCES
${BACKEND_DIR}/Sampler.h
${BACKEND_DIR}/ShaderModule.cpp
${BACKEND_DIR}/ShaderModule.h
${BACKEND_DIR}/SwapChain.cpp
${BACKEND_DIR}/SwapChain.h
${BACKEND_DIR}/Texture.cpp
${BACKEND_DIR}/Texture.h
${BACKEND_DIR}/ToBackend.h

View File

@ -49,6 +49,7 @@ namespace backend {
virtual RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) = 0;
virtual SamplerBase* CreateSampler(SamplerBuilder* builder) = 0;
virtual ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) = 0;
virtual SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) = 0;
virtual TextureBase* CreateTexture(TextureBuilder* builder) = 0;
virtual TextureViewBase* CreateTextureView(TextureViewBuilder* builder) = 0;
@ -87,6 +88,7 @@ namespace backend {
RenderPipelineBuilder* CreateRenderPipelineBuilder();
SamplerBuilder* CreateSamplerBuilder();
ShaderModuleBuilder* CreateShaderModuleBuilder();
SwapChainBuilder* CreateSwapChainBuilder();
TextureBuilder* CreateTextureBuilder();
void Tick();

View File

@ -49,6 +49,8 @@ namespace backend {
class SamplerBuilder;
class ShaderModuleBase;
class ShaderModuleBuilder;
class SwapChainBase;
class SwapChainBuilder;
class TextureBase;
class TextureBuilder;
class TextureViewBase;

View File

@ -46,8 +46,6 @@ namespace backend {
public:
FramebufferBuilder(DeviceBase* device);
bool WasConsumed() const;
// NXT API
FramebufferBase* GetResultImpl() override;
void SetRenderPass(RenderPassBase* renderPass);

113
src/backend/SwapChain.cpp Normal file
View File

@ -0,0 +1,113 @@
// 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 "backend/SwapChain.h"
#include "backend/Device.h"
#include "backend/Texture.h"
namespace backend {
// SwapChain
SwapChainBase::SwapChainBase(SwapChainBuilder* builder)
: device(builder->device), implementation(builder->implementation) {
}
SwapChainBase::~SwapChainBase() {
}
DeviceBase* SwapChainBase::GetDevice() {
return device;
}
void SwapChainBase::Configure(nxt::TextureFormat format, uint32_t width, uint32_t height) {
if (width == 0 || height == 0) {
device->HandleError("Swap chain cannot be configured to zero size");
return;
}
this->format = format;
this->width = width;
this->height = height;
}
TextureBase* SwapChainBase::GetNextTexture() {
if (width == 0) {
// If width is 0, it implies swap chain has never been configured
device->HandleError("Swap chain needs to be configured before GetNextTexture");
return nullptr;
}
auto* builder = device->CreateTextureBuilder();
builder->SetDimension(nxt::TextureDimension::e2D);
builder->SetExtent(width, height, 1);
builder->SetFormat(format);
builder->SetMipLevels(1);
builder->SetAllowedUsage(nxt::TextureUsageBit::OutputAttachment | nxt::TextureUsageBit::Present);
builder->SetInitialUsage(nxt::TextureUsageBit::OutputAttachment);
auto* texture = GetNextTextureImpl(builder);
lastNextTexture = texture;
return texture;
}
void SwapChainBase::Present(TextureBase* texture) {
if (texture != lastNextTexture) {
device->HandleError("Tried to present something other than the last NextTexture");
return;
}
if (texture->GetUsage() != nxt::TextureUsageBit::Present) {
device->HandleError("Texture has not been transitioned to the Present usage");
return;
}
implementation.Present(implementation.userData);
}
const nxtSwapChainImplementation& SwapChainBase::GetImplementation() {
return implementation;
}
// SwapChain Builder
SwapChainBuilder::SwapChainBuilder(DeviceBase* device)
: Builder(device) {
}
SwapChainBase* SwapChainBuilder::GetResultImpl() {
if (!implementation.Init) {
HandleError("Implementation not set");
return nullptr;
}
return device->CreateSwapChain(this);
}
void SwapChainBuilder::SetImplementation(uint64_t implementation) {
if (!implementation) {
HandleError("Implementation pointer is invalid");
return;
}
nxtSwapChainImplementation& impl = *reinterpret_cast<nxtSwapChainImplementation*>(implementation);
if (!impl.Init || impl.Destroy || !impl.Configure ||
!impl.GetNextTexture || !impl.Present) {
HandleError("Implementation is incomplete");
return;
}
this->implementation = impl;
}
}

68
src/backend/SwapChain.h Normal file
View File

@ -0,0 +1,68 @@
// 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_SWAPCHAIN_H_
#define BACKEND_SWAPCHAIN_H_
#include "backend/Forward.h"
#include "backend/Builder.h"
#include "backend/RefCounted.h"
#include "nxt/nxtcpp.h"
#include "nxt/nxt_wsi.h"
namespace backend {
class SwapChainBase : public RefCounted {
public:
SwapChainBase(SwapChainBuilder* builder);
~SwapChainBase();
DeviceBase* GetDevice();
// NXT API
void Configure(nxt::TextureFormat format, uint32_t width, uint32_t height);
TextureBase* GetNextTexture();
void Present(TextureBase* texture);
protected:
const nxtSwapChainImplementation& GetImplementation();
virtual TextureBase* GetNextTextureImpl(TextureBuilder* builder) = 0;
private:
DeviceBase* device = nullptr;
nxtSwapChainImplementation implementation = {};
nxt::TextureFormat format = {};
uint32_t width = 0;
uint32_t height = 0;
TextureBase* lastNextTexture = nullptr;
};
class SwapChainBuilder : public Builder<SwapChainBase> {
public:
SwapChainBuilder(DeviceBase* device);
// NXT API
SwapChainBase* GetResultImpl() override;
void SetImplementation(uint64_t implementation);
private:
friend class SwapChainBase;
nxtSwapChainImplementation implementation = {};
};
}
#endif // BACKEND_SWAPCHAIN_H_

View File

@ -112,6 +112,9 @@ namespace backend {
if (frozen) {
return false;
}
if (currentUsage == nxt::TextureUsageBit::Present) {
return false;
}
return IsUsagePossible(allowedUsage, usage);
}

View File

@ -108,6 +108,11 @@ namespace backend {
using BackendType = typename BackendTraits::TextureType;
};
template<typename BackendTraits>
struct ToBackendTraits<SwapChainBase, BackendTraits> {
using BackendType = typename BackendTraits::SwapChainType;
};
template<typename BackendTraits>
struct ToBackendTraits<TextureViewBase, BackendTraits> {
using BackendType = typename BackendTraits::TextureViewType;

View File

@ -30,6 +30,7 @@
#include "backend/d3d12/ResourceUploader.h"
#include "backend/d3d12/SamplerD3D12.h"
#include "backend/d3d12/ShaderModuleD3D12.h"
#include "backend/d3d12/SwapChainD3D12.h"
#include "backend/d3d12/TextureD3D12.h"
#include "common/Assert.h"
@ -253,8 +254,11 @@ namespace d3d12 {
ShaderModuleBase* Device::CreateShaderModule(ShaderModuleBuilder* builder) {
return new ShaderModule(this, builder);
}
SwapChainBase* Device::CreateSwapChain(SwapChainBuilder* builder) {
return new SwapChain(builder);
}
TextureBase* Device::CreateTexture(TextureBuilder* builder) {
return new Texture(this, builder);
return new Texture(builder);
}
TextureViewBase* Device::CreateTextureView(TextureViewBuilder* builder) {
return new TextureView(builder);

View File

@ -43,6 +43,7 @@ namespace d3d12 {
class RenderPipeline;
class Sampler;
class ShaderModule;
class SwapChain;
class Texture;
class TextureView;
@ -69,6 +70,7 @@ namespace d3d12 {
using RenderPipelineType = RenderPipeline;
using SamplerType = Sampler;
using ShaderModuleType = ShaderModule;
using SwapChainType = SwapChain;
using TextureType = Texture;
using TextureViewType = TextureView;
};
@ -101,6 +103,7 @@ namespace d3d12 {
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SamplerBase* CreateSampler(SamplerBuilder* builder) override;
ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
TextureBase* CreateTexture(TextureBuilder* builder) override;
TextureViewBase* CreateTextureView(TextureViewBuilder* builder) override;

View File

@ -25,4 +25,5 @@
#include "backend/d3d12/RenderPipelineD3D12.h"
#include "backend/d3d12/SamplerD3D12.h"
#include "backend/d3d12/ShaderModuleD3D12.h"
#include "backend/d3d12/SwapChainD3D12.h"
#include "backend/d3d12/TextureD3D12.h"

View File

@ -0,0 +1,46 @@
// 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 "backend/d3d12/SwapChainD3D12.h"
#include "backend/d3d12/TextureD3D12.h"
#include <nxt/nxt_wsi.h>
namespace backend {
namespace d3d12 {
SwapChain::SwapChain(SwapChainBuilder* builder)
: SwapChainBase(builder) {
const auto& im = GetImplementation();
nxtWSIContextD3D12 wsiContext = {};
// TODO(kainino@chromium.org): set up wsiContext
im.Init(im.userData, &wsiContext);
// TODO(kainino@chromium.org): set up D3D12 swapchain
}
SwapChain::~SwapChain() {
// TODO(kainino@chromium.org): clean up D3D12 swapchain
}
TextureBase* SwapChain::GetNextTextureImpl(TextureBuilder* builder) {
ComPtr<ID3D12Resource> nativeTexture = nullptr;
// TODO(kainino@chromium.org): obtain native texture from D3D12 swapchain
return new Texture(builder, nativeTexture);
}
}
}

View File

@ -0,0 +1,35 @@
// 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_D3D12_SWAPCHAIND3D12_H_
#define BACKEND_D3D12_SWAPCHAIND3D12_H_
#include "backend/SwapChain.h"
namespace backend {
namespace d3d12 {
class SwapChain : public SwapChainBase {
public:
SwapChain(SwapChainBuilder* builder);
~SwapChain();
protected:
TextureBase* GetNextTextureImpl(TextureBuilder* builder) override;
};
}
}
#endif // BACKEND_D3D12_SWAPCHAIN_D3D12_H_

View File

@ -88,8 +88,8 @@ namespace d3d12 {
}
}
Texture::Texture(Device* device, TextureBuilder* builder)
: TextureBase(builder), device(device) {
Texture::Texture(TextureBuilder* builder)
: TextureBase(builder), device(ToBackend(builder->GetDevice())) {
D3D12_RESOURCE_DESC resourceDescriptor;
resourceDescriptor.Dimension = D3D12TextureDimension(GetDimension());
@ -107,7 +107,12 @@ namespace d3d12 {
resource = device->GetResourceAllocator()->Allocate(D3D12_HEAP_TYPE_DEFAULT, resourceDescriptor, D3D12TextureUsage(GetUsage(), GetFormat()));
}
Texture::Texture(TextureBuilder* builder, ComPtr<ID3D12Resource> nativeTexture)
: TextureBase(builder), device(ToBackend(builder->GetDevice())), resource(nativeTexture) {
}
Texture::~Texture() {
// TODO(kainino@chromium.org): Maybe don't release when using the native texture constructor?
device->GetResourceAllocator()->Release(resource);
}

View File

@ -28,7 +28,8 @@ namespace d3d12 {
class Texture : public TextureBase {
public:
Texture(Device* device, TextureBuilder* builder);
Texture(TextureBuilder* builder);
Texture(TextureBuilder* builder, ComPtr<ID3D12Resource> nativeTexture);
~Texture();
DXGI_FORMAT GetD3D12Format() const;

View File

@ -22,4 +22,5 @@
#include "backend/metal/RenderPipelineMTL.h"
#include "backend/metal/SamplerMTL.h"
#include "backend/metal/ShaderModuleMTL.h"
#include "backend/metal/SwapChainMTL.h"
#include "backend/metal/TextureMTL.h"

View File

@ -49,6 +49,7 @@ namespace metal {
class RenderPipeline;
class Sampler;
class ShaderModule;
class SwapChain;
class Texture;
class TextureView;
@ -69,6 +70,7 @@ namespace metal {
using RenderPipelineType = RenderPipeline;
using SamplerType = Sampler;
using ShaderModuleType = ShaderModule;
using SwapChainType = SwapChain;
using TextureType = Texture;
using TextureViewType = TextureView;
};
@ -101,6 +103,7 @@ namespace metal {
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SamplerBase* CreateSampler(SamplerBuilder* builder) override;
ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
TextureBase* CreateTexture(TextureBuilder* builder) override;
TextureViewBase* CreateTextureView(TextureViewBuilder* builder) override;

View File

@ -24,6 +24,7 @@
#include "backend/metal/ResourceUploader.h"
#include "backend/metal/SamplerMTL.h"
#include "backend/metal/ShaderModuleMTL.h"
#include "backend/metal/SwapChainMTL.h"
#include "backend/metal/TextureMTL.h"
#include <unistd.h>
@ -135,6 +136,9 @@ namespace metal {
ShaderModuleBase* Device::CreateShaderModule(ShaderModuleBuilder* builder) {
return new ShaderModule(builder);
}
SwapChainBase* Device::CreateSwapChain(SwapChainBuilder* builder) {
return new SwapChain(builder);
}
TextureBase* Device::CreateTexture(TextureBuilder* builder) {
return new Texture(builder);
}

View File

@ -0,0 +1,37 @@
// 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_METAL_SWAPCHAINGL_H_
#define BACKEND_METAL_SWAPCHAINGL_H_
#include "backend/SwapChain.h"
namespace backend {
namespace metal {
class Device;
class SwapChain : public SwapChainBase {
public:
SwapChain(SwapChainBuilder* builder);
~SwapChain();
protected:
TextureBase* GetNextTextureImpl(TextureBuilder* builder) override;
};
}
}
#endif // BACKEND_METAL_SWAPCHAINGL_H_

View File

@ -0,0 +1,45 @@
// 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 "backend/metal/SwapChainMTL.h"
#include "backend/metal/TextureMTL.h"
#include <nxt/nxt_wsi.h>
namespace backend {
namespace metal {
SwapChain::SwapChain(SwapChainBuilder* builder)
: SwapChainBase(builder) {
const auto& im = GetImplementation();
nxtWSIContextMetal wsiContext = {};
// TODO(kainino@chromium.org): set up wsiContext
im.Init(im.userData, &wsiContext);
// TODO(kainino@chromium.org): set up Metal swapchain
}
SwapChain::~SwapChain() {
// TODO(kainino@chromium.org): clean up Metal swapchain
}
TextureBase* SwapChain::GetNextTextureImpl(TextureBuilder* builder) {
id<MTLTexture> nativeTexture = nil;
// TODO(kainino@chromium.org): obtain MTLTexture from Metal swapchain
return new Texture(builder, nativeTexture);
}
}
}

View File

@ -25,6 +25,7 @@ namespace metal {
class Texture : public TextureBase {
public:
Texture(TextureBuilder* builder);
Texture(TextureBuilder* builder, id<MTLTexture> mtlTexture);
~Texture();
id<MTLTexture> GetMTLTexture();

View File

@ -73,6 +73,11 @@ namespace metal {
mtlTexture = [mtlDevice newTextureWithDescriptor:desc];
}
Texture::Texture(TextureBuilder* builder, id<MTLTexture> mtlTexture)
: TextureBase(builder), mtlTexture(mtlTexture) {
[mtlTexture retain];
}
Texture::~Texture() {
[mtlTexture release];
}

View File

@ -87,6 +87,9 @@ namespace null {
return module;
}
SwapChainBase* Device::CreateSwapChain(SwapChainBuilder* builder) {
return new SwapChain(builder);
}
TextureBase* Device::CreateTexture(TextureBuilder* builder) {
return new Texture(builder);
}
@ -222,5 +225,19 @@ namespace null {
void Texture::TransitionUsageImpl(nxt::TextureUsageBit, nxt::TextureUsageBit) {
}
// SwapChain
SwapChain::SwapChain(SwapChainBuilder* builder)
: SwapChainBase(builder) {
const auto& im = GetImplementation();
im.Init(im.userData, nullptr);
}
SwapChain::~SwapChain() {
}
TextureBase* SwapChain::GetNextTextureImpl(TextureBuilder* builder) {
return GetDevice()->CreateTexture(builder);
}
}
}

View File

@ -32,6 +32,7 @@
#include "backend/RenderPipeline.h"
#include "backend/Sampler.h"
#include "backend/ShaderModule.h"
#include "backend/SwapChain.h"
#include "backend/Texture.h"
#include "backend/ToBackend.h"
@ -54,6 +55,7 @@ namespace null {
using RenderPipeline = RenderPipelineBase;
using Sampler = SamplerBase;
using ShaderModule = ShaderModuleBase;
class SwapChain;
class Texture;
using TextureView = TextureViewBase;
@ -74,6 +76,7 @@ namespace null {
using RenderPipelineType = RenderPipeline;
using SamplerType = Sampler;
using ShaderModuleType = ShaderModule;
using SwapChainType = SwapChain;
using TextureType = Texture;
using TextureViewType = TextureView;
};
@ -108,6 +111,7 @@ namespace null {
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SamplerBase* CreateSampler(SamplerBuilder* builder) override;
ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
TextureBase* CreateTexture(TextureBuilder* builder) override;
TextureViewBase* CreateTextureView(TextureViewBuilder* builder) override;
@ -158,13 +162,22 @@ namespace null {
class Texture : public TextureBase {
public:
Texture(TextureBuilder* buidler);
Texture(TextureBuilder* builder);
~Texture();
private:
void TransitionUsageImpl(nxt::TextureUsageBit currentUsage, nxt::TextureUsageBit targetUsage) override;
};
class SwapChain : public SwapChainBase {
public:
SwapChain(SwapChainBuilder* builder);
~SwapChain();
protected:
TextureBase* GetNextTextureImpl(TextureBuilder* builder) override;
};
}
}

View File

@ -22,4 +22,5 @@
#include "backend/opengl/RenderPipelineGL.h"
#include "backend/opengl/SamplerGL.h"
#include "backend/opengl/ShaderModuleGL.h"
#include "backend/opengl/SwapChainGL.h"
#include "backend/opengl/TextureGL.h"

View File

@ -21,6 +21,7 @@
#include "backend/opengl/PipelineLayoutGL.h"
#include "backend/opengl/RenderPipelineGL.h"
#include "backend/opengl/ShaderModuleGL.h"
#include "backend/opengl/SwapChainGL.h"
#include "backend/opengl/SamplerGL.h"
#include "backend/opengl/TextureGL.h"
@ -103,6 +104,9 @@ namespace opengl {
ShaderModuleBase* Device::CreateShaderModule(ShaderModuleBuilder* builder) {
return new ShaderModule(builder);
}
SwapChainBase* Device::CreateSwapChain(SwapChainBuilder* builder) {
return new SwapChain(builder);
}
TextureBase* Device::CreateTexture(TextureBuilder* builder) {
return new Texture(builder);
}

View File

@ -50,6 +50,7 @@ namespace opengl {
class RenderPipeline;
class Sampler;
class ShaderModule;
class SwapChain;
class Texture;
class TextureView;
@ -70,6 +71,7 @@ namespace opengl {
using RenderPipelineType = RenderPipeline;
using SamplerType = Sampler;
using ShaderModuleType = ShaderModule;
using SwapChainType = SwapChain;
using TextureType = Texture;
using TextureViewType = TextureView;
};
@ -97,6 +99,7 @@ namespace opengl {
RenderPipelineBase* CreateRenderPipeline(RenderPipelineBuilder* builder) override;
SamplerBase* CreateSampler(SamplerBuilder* builder) override;
ShaderModuleBase* CreateShaderModule(ShaderModuleBuilder* builder) override;
SwapChainBase* CreateSwapChain(SwapChainBuilder* builder) override;
TextureBase* CreateTexture(TextureBuilder* builder) override;
TextureViewBase* CreateTextureView(TextureViewBuilder* builder) override;

View File

@ -0,0 +1,43 @@
// 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 "backend/opengl/SwapChainGL.h"
#include "backend/opengl/TextureGL.h"
#include <nxt/nxt_wsi.h>
namespace backend {
namespace opengl {
SwapChain::SwapChain(SwapChainBuilder* builder)
: SwapChainBase(builder) {
const auto& im = GetImplementation();
nxtWSIContextGL wsiContext = {};
// TODO(kainino@chromium.org): set up wsiContext
im.Init(im.userData, &wsiContext);
// TODO(kainino@chromium.org): set up FBO
}
SwapChain::~SwapChain() {
// TODO(kainino@chromium.org): clean up FBO
}
TextureBase* SwapChain::GetNextTextureImpl(TextureBuilder* builder) {
return new Texture(builder, nativeTexture);
}
}
}

View File

@ -0,0 +1,42 @@
// 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_OPENGL_SWAPCHAINGL_H_
#define BACKEND_OPENGL_SWAPCHAINGL_H_
#include "backend/SwapChain.h"
#include "glad/glad.h"
namespace backend {
namespace opengl {
class Device;
class SwapChain : public SwapChainBase {
public:
SwapChain(SwapChainBuilder* builder);
~SwapChain();
protected:
TextureBase* GetNextTextureImpl(TextureBuilder* builder) override;
private:
GLuint nativeTexture = 0;
};
}
}
#endif // BACKEND_OPENGL_SWAPCHAINGL_H_

View File

@ -44,12 +44,22 @@ namespace opengl {
}
}
GLuint GenTexture() {
GLuint handle = 0;
glGenTextures(1, &handle);
return handle;
}
}
// Texture
Texture::Texture(TextureBuilder* builder)
: TextureBase(builder) {
: Texture(builder, GenTexture()) {
}
Texture::Texture(TextureBuilder* builder, GLuint handle)
: TextureBase(builder), handle(handle) {
target = TargetForDimension(GetDimension());
uint32_t width = GetWidth();
@ -58,7 +68,6 @@ namespace opengl {
auto formatInfo = GetGLFormatInfo(GetFormat());
glGenTextures(1, &handle);
glBindTexture(target, handle);
for (uint32_t i = 0; i < levels; ++i) {
@ -72,6 +81,10 @@ namespace opengl {
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels - 1);
}
Texture::~Texture() {
// TODO(kainino@chromium.org): delete texture (but only when not using the native texture constructor?)
}
GLuint Texture::GetHandle() const {
return handle;
}

View File

@ -33,6 +33,8 @@ namespace opengl {
class Texture : public TextureBase {
public:
Texture(TextureBuilder* builder);
Texture(TextureBuilder* builder, GLuint handle);
~Texture();
GLuint GetHandle() const;
GLenum GetGLTarget() const;

64
src/include/nxt/nxt_wsi.h Normal file
View File

@ -0,0 +1,64 @@
//* 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 NXT_WSI_H
#define NXT_WSI_H
#include <nxt/nxt.h>
// Error message (or nullptr if there was no error)
typedef const char* nxtSwapChainError;
typedef struct {
/// Backend-specific texture id/name/pointer
void* texture = nullptr;
} nxtSwapChainNextTexture;
typedef struct {
/// Initialize the swap chain implementation.
/// (*wsiContext) is one of nxtWSIContext{D3D12,Metal,GL}
void (*Init)(void* userData, void* wsiContext);
/// Destroy the swap chain implementation.
void (*Destroy)(void* userData);
/// Configure/reconfigure the swap chain.
nxtSwapChainError (*Configure)(void* userData, nxtTextureFormat format, uint32_t width, uint32_t height);
/// Acquire the next texture from the swap chain.
nxtSwapChainError (*GetNextTexture)(void* userData, nxtSwapChainNextTexture* nextTexture);
/// Present the last acquired texture to the screen.
nxtSwapChainError (*Present)(void* userData);
/// Each function is called with userData as its first argument.
void* userData = nullptr;
} nxtSwapChainImplementation;
#ifdef NXT_ENABLE_BACKEND_D3D12
typedef struct {
} nxtWSIContextD3D12;
#endif
#ifdef NXT_ENABLE_BACKEND_METAL
typedef struct {
} nxtWSIContextMetal;
#endif
#ifdef NXT_ENABLE_BACKEND_OPENGL
typedef struct {
} nxtWSIContextGL;
#endif
#endif // NXT_WSI_H

View File

@ -41,7 +41,7 @@ NXTExternalTarget("third_party" glad)
# ShaderC
# Prevent SPIRV-Tools from using Werror as it has a warning on MSVC
set(SPIRV_WERROR OFF)
set(SPIRV_WERROR OFF CACHE BOOL "" FORCE)
# Don't add unnecessary shaderc targets
set(SHADERC_SKIP_TESTS ON)
# Help shaderc find the non-standard paths for its dependencies