mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-06 14:43:31 +00:00
parent
28684d93ed
commit
fec8c58a97
@ -81,8 +81,10 @@ void frame() {
|
|||||||
{
|
{
|
||||||
nxtCommandBufferBuilder builder = nxtDeviceCreateCommandBufferBuilder(device);
|
nxtCommandBufferBuilder builder = nxtDeviceCreateCommandBufferBuilder(device);
|
||||||
nxtCommandBufferBuilderBeginRenderPass(builder, renderpass, framebuffer);
|
nxtCommandBufferBuilderBeginRenderPass(builder, renderpass, framebuffer);
|
||||||
|
nxtCommandBufferBuilderBeginRenderSubpass(builder);
|
||||||
nxtCommandBufferBuilderSetPipeline(builder, pipeline);
|
nxtCommandBufferBuilderSetPipeline(builder, pipeline);
|
||||||
nxtCommandBufferBuilderDrawArrays(builder, 3, 1, 0, 0);
|
nxtCommandBufferBuilderDrawArrays(builder, 3, 1, 0, 0);
|
||||||
|
nxtCommandBufferBuilderEndRenderSubpass(builder);
|
||||||
nxtCommandBufferBuilderEndRenderPass(builder);
|
nxtCommandBufferBuilderEndRenderPass(builder);
|
||||||
commands = nxtCommandBufferBuilderGetResult(builder);
|
commands = nxtCommandBufferBuilderGetResult(builder);
|
||||||
nxtCommandBufferBuilderRelease(builder);
|
nxtCommandBufferBuilderRelease(builder);
|
||||||
|
@ -445,18 +445,7 @@ namespace {
|
|||||||
device = CreateCppNXTDevice();
|
device = CreateCppNXTDevice();
|
||||||
|
|
||||||
queue = device.CreateQueueBuilder().GetResult();
|
queue = device.CreateQueueBuilder().GetResult();
|
||||||
renderpass = device.CreateRenderPassBuilder()
|
utils::CreateDefaultRenderPass(device, &renderpass, &framebuffer);
|
||||||
.SetAttachmentCount(1)
|
|
||||||
.AttachmentSetFormat(0, nxt::TextureFormat::R8G8B8A8Unorm)
|
|
||||||
.SetSubpassCount(1)
|
|
||||||
.SubpassSetColorAttachment(0, 0, 0)
|
|
||||||
.GetResult();
|
|
||||||
framebuffer = device.CreateFramebufferBuilder()
|
|
||||||
.SetRenderPass(renderpass)
|
|
||||||
// attachment 0 -> back buffer
|
|
||||||
// (implicit) // TODO(kainino@chromium.org): use the texture provided by WSI
|
|
||||||
.SetDimensions(640, 480)
|
|
||||||
.GetResult();
|
|
||||||
|
|
||||||
initBuffers();
|
initBuffers();
|
||||||
initSamplers();
|
initSamplers();
|
||||||
|
12
next.json
12
next.json
@ -591,7 +591,7 @@
|
|||||||
"name": "set attachment",
|
"name": "set attachment",
|
||||||
"args": [
|
"args": [
|
||||||
{"name": "attachment slot", "type": "uint32_t"},
|
{"name": "attachment slot", "type": "uint32_t"},
|
||||||
{"name": "texture views", "type": "texture view"}
|
{"name": "texture view", "type": "texture view"}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -762,6 +762,13 @@
|
|||||||
{"name": "output attachment location", "type": "uint32_t"},
|
{"name": "output attachment location", "type": "uint32_t"},
|
||||||
{"name": "attachment slot", "type": "uint32_t"}
|
{"name": "attachment slot", "type": "uint32_t"}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "subpass set depth stencil attachment",
|
||||||
|
"args": [
|
||||||
|
{"name": "subpass index", "type": "uint32_t"},
|
||||||
|
{"name": "attachment slot", "type": "uint32_t"}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -936,7 +943,8 @@
|
|||||||
"texture format": {
|
"texture format": {
|
||||||
"category": "enum",
|
"category": "enum",
|
||||||
"values": [
|
"values": [
|
||||||
{"value": 0, "name": "r8 g8 b8 a8 unorm"}
|
{"value": 0, "name": "r8 g8 b8 a8 unorm"},
|
||||||
|
{"value": 1, "name": "d32 float s8 uint"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"vertex format": {
|
"vertex format": {
|
||||||
|
@ -126,6 +126,10 @@ namespace backend {
|
|||||||
HandleError("Render pass subpass count not set yet");
|
HandleError("Render pass subpass count not set yet");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if ((propertiesSet & RENDERPASS_PROPERTY_ATTACHMENT_COUNT) == 0) {
|
||||||
|
HandleError("Render pass attachment count not set yet");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (subpass >= subpasses.size()) {
|
if (subpass >= subpasses.size()) {
|
||||||
HandleError("Subpass index out of bounds");
|
HandleError("Subpass index out of bounds");
|
||||||
return;
|
return;
|
||||||
@ -147,4 +151,30 @@ namespace backend {
|
|||||||
subpasses[subpass].colorAttachments[outputAttachmentLocation] = attachmentSlot;
|
subpasses[subpass].colorAttachments[outputAttachmentLocation] = attachmentSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderPassBuilder::SubpassSetDepthStencilAttachment(uint32_t subpass, uint32_t attachmentSlot) {
|
||||||
|
if ((propertiesSet & RENDERPASS_PROPERTY_SUBPASS_COUNT) == 0) {
|
||||||
|
HandleError("Render pass subpass count not set yet");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((propertiesSet & RENDERPASS_PROPERTY_ATTACHMENT_COUNT) == 0) {
|
||||||
|
HandleError("Render pass attachment count not set yet");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (subpass >= subpasses.size()) {
|
||||||
|
HandleError("Subpass index out of bounds");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (attachmentSlot >= attachments.size()) {
|
||||||
|
HandleError("Subpass attachment slot out of bounds");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (subpasses[subpass].depthStencilAttachmentSet) {
|
||||||
|
HandleError("Subpass depth-stencil attachment already set");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
subpasses[subpass].depthStencilAttachmentSet = true;
|
||||||
|
subpasses[subpass].depthStencilAttachment = attachmentSlot;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,8 @@ namespace backend {
|
|||||||
struct SubpassInfo {
|
struct SubpassInfo {
|
||||||
std::bitset<kMaxColorAttachments> colorAttachmentsSet;
|
std::bitset<kMaxColorAttachments> colorAttachmentsSet;
|
||||||
std::array<uint32_t, kMaxColorAttachments> colorAttachments;
|
std::array<uint32_t, kMaxColorAttachments> colorAttachments;
|
||||||
|
bool depthStencilAttachmentSet = false;
|
||||||
|
uint32_t depthStencilAttachment = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t GetAttachmentCount() const;
|
uint32_t GetAttachmentCount() const;
|
||||||
@ -64,6 +66,7 @@ namespace backend {
|
|||||||
void AttachmentSetFormat(uint32_t attachmentSlot, nxt::TextureFormat format);
|
void AttachmentSetFormat(uint32_t attachmentSlot, nxt::TextureFormat format);
|
||||||
void SetSubpassCount(uint32_t subpassCount);
|
void SetSubpassCount(uint32_t subpassCount);
|
||||||
void SubpassSetColorAttachment(uint32_t subpass, uint32_t outputAttachmentLocation, uint32_t attachmentSlot);
|
void SubpassSetColorAttachment(uint32_t subpass, uint32_t outputAttachmentLocation, uint32_t attachmentSlot);
|
||||||
|
void SubpassSetDepthStencilAttachment(uint32_t subpass, uint32_t attachmentSlot);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class RenderPassBase;
|
friend class RenderPassBase;
|
||||||
|
@ -23,11 +23,36 @@ namespace backend {
|
|||||||
switch (format) {
|
switch (format) {
|
||||||
case nxt::TextureFormat::R8G8B8A8Unorm:
|
case nxt::TextureFormat::R8G8B8A8Unorm:
|
||||||
return 4;
|
return 4;
|
||||||
|
case nxt::TextureFormat::D32FloatS8Uint:
|
||||||
|
return 8;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TextureFormatHasDepth(nxt::TextureFormat format) {
|
||||||
|
switch (format) {
|
||||||
|
case nxt::TextureFormat::R8G8B8A8Unorm:
|
||||||
|
return false;
|
||||||
|
case nxt::TextureFormat::D32FloatS8Uint:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextureFormatHasStencil(nxt::TextureFormat format) {
|
||||||
|
switch (format) {
|
||||||
|
case nxt::TextureFormat::R8G8B8A8Unorm:
|
||||||
|
return false;
|
||||||
|
case nxt::TextureFormat::D32FloatS8Uint:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// TextureBase
|
// TextureBase
|
||||||
|
|
||||||
TextureBase::TextureBase(TextureBuilder* builder)
|
TextureBase::TextureBase(TextureBuilder* builder)
|
||||||
@ -95,15 +120,6 @@ namespace backend {
|
|||||||
currentUsage = usage;
|
currentUsage = usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureBase::IsDepthFormat(nxt::TextureFormat format) {
|
|
||||||
switch (format) {
|
|
||||||
case nxt::TextureFormat::R8G8B8A8Unorm:
|
|
||||||
return false;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextureBase::TransitionUsage(nxt::TextureUsageBit usage) {
|
void TextureBase::TransitionUsage(nxt::TextureUsageBit usage) {
|
||||||
if (!IsTransitionPossible(usage)) {
|
if (!IsTransitionPossible(usage)) {
|
||||||
device->HandleError("Texture frozen or usage not allowed");
|
device->HandleError("Texture frozen or usage not allowed");
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
size_t TextureFormatPixelSize(nxt::TextureFormat format);
|
size_t TextureFormatPixelSize(nxt::TextureFormat format);
|
||||||
|
bool TextureFormatHasDepth(nxt::TextureFormat format);
|
||||||
|
bool TextureFormatHasStencil(nxt::TextureFormat format);
|
||||||
|
|
||||||
class TextureBase : public RefCounted {
|
class TextureBase : public RefCounted {
|
||||||
public:
|
public:
|
||||||
@ -43,8 +45,6 @@ namespace backend {
|
|||||||
bool IsTransitionPossible(nxt::TextureUsageBit usage) const;
|
bool IsTransitionPossible(nxt::TextureUsageBit usage) const;
|
||||||
void UpdateUsageInternal(nxt::TextureUsageBit usage);
|
void UpdateUsageInternal(nxt::TextureUsageBit usage);
|
||||||
|
|
||||||
static bool IsDepthFormat(nxt::TextureFormat format);
|
|
||||||
|
|
||||||
DeviceBase* GetDevice();
|
DeviceBase* GetDevice();
|
||||||
|
|
||||||
// NXT API
|
// NXT API
|
||||||
|
@ -204,12 +204,7 @@ namespace d3d12 {
|
|||||||
d3d12Location.PlacedFootprint.Footprint.Height = textureLocation.height;
|
d3d12Location.PlacedFootprint.Footprint.Height = textureLocation.height;
|
||||||
d3d12Location.PlacedFootprint.Footprint.Depth = textureLocation.depth;
|
d3d12Location.PlacedFootprint.Footprint.Depth = textureLocation.depth;
|
||||||
|
|
||||||
uint32_t texelSize = 0;
|
size_t texelSize = TextureFormatPixelSize(texture->GetFormat());
|
||||||
switch (texture->GetFormat()) {
|
|
||||||
case nxt::TextureFormat::R8G8B8A8Unorm:
|
|
||||||
texelSize = 4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
uint32_t rowSize = textureLocation.width * texelSize;
|
uint32_t rowSize = textureLocation.width * texelSize;
|
||||||
d3d12Location.PlacedFootprint.Footprint.RowPitch = ((rowSize - 1) / D3D12_TEXTURE_DATA_PITCH_ALIGNMENT + 1) * D3D12_TEXTURE_DATA_PITCH_ALIGNMENT;
|
d3d12Location.PlacedFootprint.Footprint.RowPitch = ((rowSize - 1) / D3D12_TEXTURE_DATA_PITCH_ALIGNMENT + 1) * D3D12_TEXTURE_DATA_PITCH_ALIGNMENT;
|
||||||
|
|
||||||
|
@ -49,9 +49,9 @@ namespace d3d12 {
|
|||||||
return backendDevice->GetCommandQueue();
|
return backendDevice->GetCommandQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetNextTexture(nxtDevice device, ComPtr<ID3D12Resource> resource, ComPtr<ID3D12Resource> depthResource) {
|
void SetNextTexture(nxtDevice device, ComPtr<ID3D12Resource> resource) {
|
||||||
Device* backendDevice = reinterpret_cast<Device*>(device);
|
Device* backendDevice = reinterpret_cast<Device*>(device);
|
||||||
backendDevice->SetNextTexture(resource, depthResource);
|
backendDevice->SetNextTexture(resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t GetSerial(const nxtDevice device) {
|
uint64_t GetSerial(const nxtDevice device) {
|
||||||
@ -160,14 +160,10 @@ namespace d3d12 {
|
|||||||
return nextTexture;
|
return nextTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
ComPtr<ID3D12Resource> Device::GetCurrentDepthTexture() {
|
void Device::SetNextTexture(ComPtr<ID3D12Resource> resource) {
|
||||||
return nextDepthTexture;
|
nextTexture = resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::SetNextTexture(ComPtr<ID3D12Resource> resource, ComPtr<ID3D12Resource> depthResource) {
|
|
||||||
nextTexture = resource;
|
|
||||||
nextDepthTexture = depthResource;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Device::TickImpl() {
|
void Device::TickImpl() {
|
||||||
// Perform cleanup operations to free unused objects
|
// Perform cleanup operations to free unused objects
|
||||||
|
@ -124,8 +124,7 @@ namespace d3d12 {
|
|||||||
ComPtr<ID3D12GraphicsCommandList> GetPendingCommandList();
|
ComPtr<ID3D12GraphicsCommandList> GetPendingCommandList();
|
||||||
|
|
||||||
ComPtr<ID3D12Resource> GetCurrentTexture();
|
ComPtr<ID3D12Resource> GetCurrentTexture();
|
||||||
ComPtr<ID3D12Resource> GetCurrentDepthTexture();
|
void SetNextTexture(ComPtr<ID3D12Resource> resource);
|
||||||
void SetNextTexture(ComPtr<ID3D12Resource> resource, ComPtr<ID3D12Resource> depthResource);
|
|
||||||
|
|
||||||
uint64_t GetSerial() const;
|
uint64_t GetSerial() const;
|
||||||
void NextSerial();
|
void NextSerial();
|
||||||
@ -153,7 +152,6 @@ namespace d3d12 {
|
|||||||
} pendingCommands;
|
} pendingCommands;
|
||||||
|
|
||||||
ComPtr<ID3D12Resource> nextTexture;
|
ComPtr<ID3D12Resource> nextTexture;
|
||||||
ComPtr<ID3D12Resource> nextDepthTexture;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DepthStencilState : public DepthStencilStateBase {
|
class DepthStencilState : public DepthStencilStateBase {
|
||||||
|
@ -23,73 +23,79 @@ namespace d3d12 {
|
|||||||
|
|
||||||
Framebuffer::Framebuffer(Device* device, FramebufferBuilder* builder)
|
Framebuffer::Framebuffer(Device* device, FramebufferBuilder* builder)
|
||||||
: FramebufferBase(builder), device(device) {
|
: FramebufferBase(builder), device(device) {
|
||||||
|
|
||||||
RenderPass* renderPass = ToBackend(GetRenderPass());
|
RenderPass* renderPass = ToBackend(GetRenderPass());
|
||||||
uint32_t attachmentCount = renderPass->GetAttachmentCount();
|
|
||||||
rtvHeap = device->GetDescriptorHeapAllocator()->AllocateCPUHeap(D3D12_DESCRIPTOR_HEAP_TYPE_RTV, attachmentCount);
|
|
||||||
|
|
||||||
bool usingBackbuffer = false; // HACK(enga@google.com): workaround for not having depth attachments
|
uint32_t rtvCount = 0, dsvCount = 0;
|
||||||
uint32_t rtvIndex = 0;
|
attachmentHeapIndices.resize(renderPass->GetAttachmentCount());
|
||||||
|
for (uint32_t attachment = 0; attachment < renderPass->GetAttachmentCount(); ++attachment) {
|
||||||
for (uint32_t attachment = 0; attachment < attachmentCount; ++attachment) {
|
|
||||||
auto* textureView = GetTextureView(attachment);
|
auto* textureView = GetTextureView(attachment);
|
||||||
if (textureView) {
|
if (!textureView) {
|
||||||
ComPtr<ID3D12Resource> texture = ToBackend(textureView->GetTexture())->GetD3D12Resource();
|
// TODO(kainino@chromium.org): null=backbuffer hack
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvHeap.GetCPUHandle(rtvIndex++);
|
attachmentHeapIndices[attachment] = rtvCount++;
|
||||||
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = ToBackend(textureView)->GetRTVDescriptor();
|
continue;
|
||||||
|
}
|
||||||
device->GetD3D12Device()->CreateRenderTargetView(texture.Get(), &rtvDesc, rtvHandle);
|
auto format = textureView->GetTexture()->GetFormat();
|
||||||
|
if (TextureFormatHasDepth(format) || TextureFormatHasStencil(format)) {
|
||||||
|
attachmentHeapIndices[attachment] = dsvCount++;
|
||||||
} else {
|
} else {
|
||||||
// TODO(enga@google.com) no attachment. This will use the backbuffer. Remove when this hack is removed
|
attachmentHeapIndices[attachment] = rtvCount++;
|
||||||
usingBackbuffer = true;
|
|
||||||
rtvIndex++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(enga@google.com): load depth attachment from subpass
|
if (rtvCount) {
|
||||||
if (usingBackbuffer) {
|
rtvHeap = device->GetDescriptorHeapAllocator()->AllocateCPUHeap(
|
||||||
dsvHeap = device->GetDescriptorHeapAllocator()->AllocateCPUHeap(D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1);
|
D3D12_DESCRIPTOR_HEAP_TYPE_RTV, rtvCount);
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = dsvHeap.GetCPUHandle(0);
|
}
|
||||||
|
if (dsvCount) {
|
||||||
|
dsvHeap = device->GetDescriptorHeapAllocator()->AllocateCPUHeap(
|
||||||
|
D3D12_DESCRIPTOR_HEAP_TYPE_DSV, dsvCount);
|
||||||
|
}
|
||||||
|
|
||||||
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc;
|
for (uint32_t attachment = 0; attachment < renderPass->GetAttachmentCount(); ++attachment) {
|
||||||
dsvDesc.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
|
uint32_t heapIndex = attachmentHeapIndices[attachment];
|
||||||
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
|
auto* textureView = GetTextureView(attachment);
|
||||||
dsvDesc.Texture2D.MipSlice = 0;
|
if (!textureView) {
|
||||||
dsvDesc.Flags = D3D12_DSV_FLAG_NONE;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
device->GetD3D12Device()->CreateDepthStencilView(device->GetCurrentDepthTexture().Get(), &dsvDesc, dsvHandle);
|
ComPtr<ID3D12Resource> texture = ToBackend(textureView->GetTexture())->GetD3D12Resource();
|
||||||
|
auto format = textureView->GetTexture()->GetFormat();
|
||||||
|
if (TextureFormatHasDepth(format) || TextureFormatHasStencil(format)) {
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = dsvHeap.GetCPUHandle(heapIndex);
|
||||||
|
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc = ToBackend(textureView)->GetDSVDescriptor();
|
||||||
|
device->GetD3D12Device()->CreateDepthStencilView(texture.Get(), &dsvDesc, dsvHandle);
|
||||||
|
} else {
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvHeap.GetCPUHandle(heapIndex);
|
||||||
|
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = ToBackend(textureView)->GetRTVDescriptor();
|
||||||
|
device->GetD3D12Device()->CreateRenderTargetView(texture.Get(), &rtvDesc, rtvHandle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Framebuffer::OMSetRenderTargetArgs Framebuffer::GetSubpassOMSetRenderTargetArgs(uint32_t subpassIndex) {
|
Framebuffer::OMSetRenderTargetArgs Framebuffer::GetSubpassOMSetRenderTargetArgs(uint32_t subpassIndex) {
|
||||||
const auto& subpassInfo = GetRenderPass()->GetSubpassInfo(subpassIndex);
|
const auto& subpassInfo = GetRenderPass()->GetSubpassInfo(subpassIndex);
|
||||||
|
OMSetRenderTargetArgs args = {};
|
||||||
bool usingBackbuffer = false; // HACK(enga@google.com): workaround for not having depth attachments
|
|
||||||
|
|
||||||
OMSetRenderTargetArgs args;
|
|
||||||
args.numRTVs = 0;
|
|
||||||
|
|
||||||
for (uint32_t index : IterateBitSet(subpassInfo.colorAttachmentsSet)) {
|
for (uint32_t index : IterateBitSet(subpassInfo.colorAttachmentsSet)) {
|
||||||
|
uint32_t heapIndex = attachmentHeapIndices[subpassInfo.colorAttachments[index]];
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvHeap.GetCPUHandle(heapIndex);
|
||||||
|
|
||||||
uint32_t attachment = subpassInfo.colorAttachments[index];
|
uint32_t attachment = subpassInfo.colorAttachments[index];
|
||||||
const auto& attachmentInfo = GetRenderPass()->GetAttachmentInfo(attachment);
|
|
||||||
|
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvHeap.GetCPUHandle(attachment);
|
|
||||||
args.RTVs[args.numRTVs++] = rtvHandle;
|
|
||||||
if (!GetTextureView(attachment)) {
|
if (!GetTextureView(attachment)) {
|
||||||
usingBackbuffer = true;
|
// TODO(kainino@chromium.org): null=backbuffer hack
|
||||||
|
|
||||||
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
|
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
|
||||||
rtvDesc.Format = D3D12TextureFormat(attachmentInfo.format);
|
rtvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
|
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
|
||||||
rtvDesc.Texture2D.MipSlice = 0;
|
rtvDesc.Texture2D.MipSlice = 0;
|
||||||
rtvDesc.Texture2D.PlaneSlice = 0;
|
rtvDesc.Texture2D.PlaneSlice = 0;
|
||||||
|
|
||||||
device->GetD3D12Device()->CreateRenderTargetView(device->GetCurrentTexture().Get(), &rtvDesc, rtvHandle);
|
device->GetD3D12Device()->CreateRenderTargetView(device->GetCurrentTexture().Get(), &rtvDesc, rtvHandle);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (usingBackbuffer) {
|
args.RTVs[args.numRTVs++] = rtvHandle;
|
||||||
args.dsv = dsvHeap.GetCPUHandle(0);
|
}
|
||||||
|
if (subpassInfo.depthStencilAttachmentSet) {
|
||||||
|
uint32_t heapIndex = attachmentHeapIndices[subpassInfo.depthStencilAttachment];
|
||||||
|
args.dsv = dsvHeap.GetCPUHandle(heapIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
#include "backend/d3d12/d3d12_platform.h"
|
#include "backend/d3d12/d3d12_platform.h"
|
||||||
#include "backend/d3d12/DescriptorHeapAllocator.h"
|
#include "backend/d3d12/DescriptorHeapAllocator.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
namespace d3d12 {
|
namespace d3d12 {
|
||||||
|
|
||||||
@ -29,9 +31,9 @@ namespace d3d12 {
|
|||||||
class Framebuffer : public FramebufferBase {
|
class Framebuffer : public FramebufferBase {
|
||||||
public:
|
public:
|
||||||
struct OMSetRenderTargetArgs {
|
struct OMSetRenderTargetArgs {
|
||||||
unsigned int numRTVs;
|
unsigned int numRTVs = 0;
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE RTVs[kMaxColorAttachments] = {};
|
D3D12_CPU_DESCRIPTOR_HANDLE RTVs[kMaxColorAttachments] = {};
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE dsv = { 0 };
|
D3D12_CPU_DESCRIPTOR_HANDLE dsv = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
Framebuffer(Device* device, FramebufferBuilder* builder);
|
Framebuffer(Device* device, FramebufferBuilder* builder);
|
||||||
@ -41,6 +43,9 @@ namespace d3d12 {
|
|||||||
Device* device;
|
Device* device;
|
||||||
DescriptorHeapHandle rtvHeap;
|
DescriptorHeapHandle rtvHeap;
|
||||||
DescriptorHeapHandle dsvHeap;
|
DescriptorHeapHandle dsvHeap;
|
||||||
|
|
||||||
|
// Indices into either the RTV or DSV heap, depending on texture format.
|
||||||
|
std::vector<uint32_t> attachmentHeapIndices;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,9 +37,10 @@ namespace d3d12 {
|
|||||||
resourceState |= D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
|
resourceState |= D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
|
||||||
}
|
}
|
||||||
if (usage & nxt::TextureUsageBit::OutputAttachment) {
|
if (usage & nxt::TextureUsageBit::OutputAttachment) {
|
||||||
resourceState |= D3D12_RESOURCE_STATE_RENDER_TARGET;
|
if (TextureFormatHasDepth(format) || TextureFormatHasStencil(format)) {
|
||||||
if (TextureBase::IsDepthFormat(format)) {
|
|
||||||
resourceState |= D3D12_RESOURCE_STATE_DEPTH_WRITE;
|
resourceState |= D3D12_RESOURCE_STATE_DEPTH_WRITE;
|
||||||
|
} else {
|
||||||
|
resourceState |= D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,12 +54,15 @@ namespace d3d12 {
|
|||||||
flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
||||||
}
|
}
|
||||||
if (usage & nxt::TextureUsageBit::OutputAttachment) {
|
if (usage & nxt::TextureUsageBit::OutputAttachment) {
|
||||||
flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
if (TextureFormatHasDepth(format) || TextureFormatHasStencil(format)) {
|
||||||
if (TextureBase::IsDepthFormat(format)) {
|
|
||||||
flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
|
flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
|
||||||
|
} else {
|
||||||
|
flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASSERT(!(flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) ||
|
||||||
|
flags == D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL);
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,6 +81,8 @@ namespace d3d12 {
|
|||||||
switch (format) {
|
switch (format) {
|
||||||
case nxt::TextureFormat::R8G8B8A8Unorm:
|
case nxt::TextureFormat::R8G8B8A8Unorm:
|
||||||
return DXGI_FORMAT_R8G8B8A8_UNORM;
|
return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
case nxt::TextureFormat::D32FloatS8Uint:
|
||||||
|
return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
@ -96,7 +102,7 @@ namespace d3d12 {
|
|||||||
resourceDescriptor.SampleDesc.Count = 1;
|
resourceDescriptor.SampleDesc.Count = 1;
|
||||||
resourceDescriptor.SampleDesc.Quality = 0;
|
resourceDescriptor.SampleDesc.Quality = 0;
|
||||||
resourceDescriptor.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
resourceDescriptor.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||||
resourceDescriptor.Flags = D3D12ResourceFlags(GetUsage(), GetFormat());
|
resourceDescriptor.Flags = D3D12ResourceFlags(GetAllowedUsage(), GetFormat());
|
||||||
|
|
||||||
resource = device->GetResourceAllocator()->Allocate(D3D12_HEAP_TYPE_DEFAULT, resourceDescriptor, D3D12TextureUsage(GetUsage(), GetFormat()));
|
resource = device->GetResourceAllocator()->Allocate(D3D12_HEAP_TYPE_DEFAULT, resourceDescriptor, D3D12TextureUsage(GetUsage(), GetFormat()));
|
||||||
}
|
}
|
||||||
@ -167,5 +173,14 @@ namespace d3d12 {
|
|||||||
return rtvDesc;
|
return rtvDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
D3D12_DEPTH_STENCIL_VIEW_DESC TextureView::GetDSVDescriptor() {
|
||||||
|
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc;
|
||||||
|
dsvDesc.Format = ToBackend(GetTexture())->GetD3D12Format();
|
||||||
|
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
|
||||||
|
dsvDesc.Texture2D.MipSlice = 0;
|
||||||
|
dsvDesc.Flags = D3D12_DSV_FLAG_NONE;
|
||||||
|
return dsvDesc;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ namespace d3d12 {
|
|||||||
|
|
||||||
const D3D12_SHADER_RESOURCE_VIEW_DESC& GetSRVDescriptor() const;
|
const D3D12_SHADER_RESOURCE_VIEW_DESC& GetSRVDescriptor() const;
|
||||||
D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor();
|
D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor();
|
||||||
|
D3D12_DEPTH_STENCIL_VIEW_DESC GetDSVDescriptor();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||||
|
@ -86,7 +86,6 @@ namespace metal {
|
|||||||
const auto& info = currentRenderPass->GetSubpassInfo(subpass);
|
const auto& info = currentRenderPass->GetSubpassInfo(subpass);
|
||||||
|
|
||||||
MTLRenderPassDescriptor* descriptor = [MTLRenderPassDescriptor renderPassDescriptor];
|
MTLRenderPassDescriptor* descriptor = [MTLRenderPassDescriptor renderPassDescriptor];
|
||||||
bool usingBackbuffer = false; // HACK(kainino@chromium.org): workaround for not having depth attachments
|
|
||||||
for (uint32_t index = 0; index < info.colorAttachments.size(); ++index) {
|
for (uint32_t index = 0; index < info.colorAttachments.size(); ++index) {
|
||||||
uint32_t attachment = info.colorAttachments[index];
|
uint32_t attachment = info.colorAttachments[index];
|
||||||
|
|
||||||
@ -98,19 +97,31 @@ namespace metal {
|
|||||||
texture = ToBackend(textureView->GetTexture())->GetMTLTexture();
|
texture = ToBackend(textureView->GetTexture())->GetMTLTexture();
|
||||||
} else {
|
} else {
|
||||||
texture = device->GetCurrentTexture();
|
texture = device->GetCurrentTexture();
|
||||||
usingBackbuffer = true;
|
|
||||||
}
|
}
|
||||||
descriptor.colorAttachments[index].texture = texture;
|
descriptor.colorAttachments[index].texture = texture;
|
||||||
descriptor.colorAttachments[index].loadAction = MTLLoadActionClear;
|
descriptor.colorAttachments[index].loadAction = MTLLoadActionLoad;
|
||||||
descriptor.colorAttachments[index].clearColor = MTLClearColorMake(0.0, 0.0, 0.0, 0.0);
|
descriptor.colorAttachments[index].clearColor = MTLClearColorMake(0.0, 0.0, 0.0, 0.0);
|
||||||
descriptor.colorAttachments[index].storeAction = MTLStoreActionStore;
|
descriptor.colorAttachments[index].storeAction = MTLStoreActionStore;
|
||||||
}
|
}
|
||||||
// TODO(kainino@chromium.org): load depth attachment from subpass
|
if (info.depthStencilAttachmentSet) {
|
||||||
if (usingBackbuffer) {
|
uint32_t attachment = info.depthStencilAttachment;
|
||||||
descriptor.depthAttachment.texture = device->GetCurrentDepthTexture();
|
|
||||||
descriptor.depthAttachment.loadAction = MTLLoadActionLoad;
|
auto textureView = currentFramebuffer->GetTextureView(attachment);
|
||||||
|
id<MTLTexture> texture = ToBackend(textureView->GetTexture())->GetMTLTexture();
|
||||||
|
nxt::TextureFormat format = textureView->GetTexture()->GetFormat();
|
||||||
|
if (TextureFormatHasDepth(format)) {
|
||||||
|
descriptor.depthAttachment.texture = texture;
|
||||||
|
descriptor.depthAttachment.loadAction = MTLLoadActionClear;
|
||||||
|
descriptor.depthAttachment.clearDepth = 1.0;
|
||||||
descriptor.depthAttachment.storeAction = MTLStoreActionStore;
|
descriptor.depthAttachment.storeAction = MTLStoreActionStore;
|
||||||
}
|
}
|
||||||
|
if (TextureFormatHasStencil(format)) {
|
||||||
|
descriptor.stencilAttachment.texture = texture;
|
||||||
|
descriptor.stencilAttachment.loadAction = MTLLoadActionClear;
|
||||||
|
descriptor.stencilAttachment.clearStencil = 0;
|
||||||
|
descriptor.stencilAttachment.storeAction = MTLStoreActionStore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render = [commandBuffer renderCommandEncoderWithDescriptor:descriptor];
|
render = [commandBuffer renderCommandEncoderWithDescriptor:descriptor];
|
||||||
// TODO(cwallez@chromium.org): does any state need to be reset?
|
// TODO(cwallez@chromium.org): does any state need to be reset?
|
||||||
|
@ -108,7 +108,6 @@ namespace metal {
|
|||||||
|
|
||||||
id<MTLDevice> GetMTLDevice();
|
id<MTLDevice> GetMTLDevice();
|
||||||
id<MTLTexture> GetCurrentTexture();
|
id<MTLTexture> GetCurrentTexture();
|
||||||
id<MTLTexture> GetCurrentDepthTexture();
|
|
||||||
|
|
||||||
id<MTLCommandBuffer> GetPendingCommandBuffer();
|
id<MTLCommandBuffer> GetPendingCommandBuffer();
|
||||||
void SubmitPendingCommandBuffer();
|
void SubmitPendingCommandBuffer();
|
||||||
@ -127,7 +126,6 @@ namespace metal {
|
|||||||
|
|
||||||
id<CAMetalDrawable> currentDrawable = nil;
|
id<CAMetalDrawable> currentDrawable = nil;
|
||||||
id<MTLTexture> currentTexture = nil;
|
id<MTLTexture> currentTexture = nil;
|
||||||
id<MTLTexture> currentDepthTexture = nil;
|
|
||||||
|
|
||||||
Serial finishedCommandSerial = 0;
|
Serial finishedCommandSerial = 0;
|
||||||
Serial pendingCommandSerial = 1;
|
Serial pendingCommandSerial = 1;
|
||||||
|
@ -74,9 +74,6 @@ namespace metal {
|
|||||||
|
|
||||||
[currentTexture release];
|
[currentTexture release];
|
||||||
currentTexture = nil;
|
currentTexture = nil;
|
||||||
|
|
||||||
[currentDepthTexture release];
|
|
||||||
currentDepthTexture = nil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
|
BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
|
||||||
@ -146,32 +143,11 @@ namespace metal {
|
|||||||
currentTexture = drawable.texture;
|
currentTexture = drawable.texture;
|
||||||
[currentTexture retain];
|
[currentTexture retain];
|
||||||
|
|
||||||
if (currentDepthTexture == nil ||
|
|
||||||
currentTexture.width != currentDepthTexture.width ||
|
|
||||||
currentTexture.height != currentDepthTexture.height) {
|
|
||||||
if (currentDepthTexture != nil) {
|
|
||||||
[currentDepthTexture release];
|
|
||||||
}
|
|
||||||
MTLTextureDescriptor* depthDescriptor = [MTLTextureDescriptor
|
|
||||||
texture2DDescriptorWithPixelFormat:MTLPixelFormatDepth32Float
|
|
||||||
width:currentTexture.width
|
|
||||||
height:currentTexture.height
|
|
||||||
mipmapped:NO];
|
|
||||||
depthDescriptor.textureType = MTLTextureType2D;
|
|
||||||
depthDescriptor.usage = MTLTextureUsageRenderTarget;
|
|
||||||
depthDescriptor.storageMode = MTLStorageModePrivate;
|
|
||||||
currentDepthTexture = [mtlDevice newTextureWithDescriptor:depthDescriptor];
|
|
||||||
}
|
|
||||||
|
|
||||||
MTLRenderPassDescriptor* passDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
|
MTLRenderPassDescriptor* passDescriptor = [MTLRenderPassDescriptor renderPassDescriptor];
|
||||||
passDescriptor.colorAttachments[0].texture = currentTexture;
|
passDescriptor.colorAttachments[0].texture = currentTexture;
|
||||||
passDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
|
passDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
|
||||||
passDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
|
passDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
|
||||||
passDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.0, 0.0, 0.0, 1.0);
|
passDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.0, 0.0, 0.0, 1.0);
|
||||||
passDescriptor.depthAttachment.texture = currentDepthTexture;
|
|
||||||
passDescriptor.depthAttachment.loadAction = MTLLoadActionClear;
|
|
||||||
passDescriptor.depthAttachment.storeAction = MTLStoreActionStore;
|
|
||||||
passDescriptor.depthAttachment.clearDepth = 1.0;
|
|
||||||
|
|
||||||
|
|
||||||
id<MTLCommandBuffer> commandBuffer = [commandQueue commandBuffer];
|
id<MTLCommandBuffer> commandBuffer = [commandQueue commandBuffer];
|
||||||
@ -195,10 +171,6 @@ namespace metal {
|
|||||||
return currentTexture;
|
return currentTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
id<MTLTexture> Device::GetCurrentDepthTexture() {
|
|
||||||
return currentDepthTexture;
|
|
||||||
}
|
|
||||||
|
|
||||||
id<MTLCommandBuffer> Device::GetPendingCommandBuffer() {
|
id<MTLCommandBuffer> Device::GetPendingCommandBuffer() {
|
||||||
if (pendingCommands == nil) {
|
if (pendingCommands == nil) {
|
||||||
pendingCommands = [commandQueue commandBuffer];
|
pendingCommands = [commandQueue commandBuffer];
|
||||||
|
@ -24,6 +24,8 @@ namespace metal {
|
|||||||
switch (format) {
|
switch (format) {
|
||||||
case nxt::TextureFormat::R8G8B8A8Unorm:
|
case nxt::TextureFormat::R8G8B8A8Unorm:
|
||||||
return MTLPixelFormatRGBA8Unorm;
|
return MTLPixelFormatRGBA8Unorm;
|
||||||
|
case nxt::TextureFormat::D32FloatS8Uint:
|
||||||
|
return MTLPixelFormatDepth32Float_Stencil8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +67,7 @@ namespace metal {
|
|||||||
desc.depth = GetDepth();
|
desc.depth = GetDepth();
|
||||||
desc.mipmapLevelCount = GetNumMipLevels();
|
desc.mipmapLevelCount = GetNumMipLevels();
|
||||||
desc.arrayLength = 1;
|
desc.arrayLength = 1;
|
||||||
|
desc.storageMode = MTLStorageModePrivate;
|
||||||
|
|
||||||
auto mtlDevice = ToBackend(builder->GetDevice())->GetMTLDevice();
|
auto mtlDevice = ToBackend(builder->GetDevice())->GetMTLDevice();
|
||||||
mtlTexture = [mtlDevice newTextureWithDescriptor:desc];
|
mtlTexture = [mtlDevice newTextureWithDescriptor:desc];
|
||||||
|
@ -103,7 +103,6 @@ namespace opengl {
|
|||||||
auto* device = ToBackend(GetDevice());
|
auto* device = ToBackend(GetDevice());
|
||||||
const auto& info = currentRenderPass->GetSubpassInfo(currentSubpass);
|
const auto& info = currentRenderPass->GetSubpassInfo(currentSubpass);
|
||||||
|
|
||||||
bool usingBackbuffer = false; // HACK(kainino@chromium.org): workaround for not having depth attachments
|
|
||||||
for (uint32_t index = 0; index < info.colorAttachments.size(); ++index) {
|
for (uint32_t index = 0; index < info.colorAttachments.size(); ++index) {
|
||||||
uint32_t attachment = info.colorAttachments[index];
|
uint32_t attachment = info.colorAttachments[index];
|
||||||
|
|
||||||
@ -115,16 +114,35 @@ namespace opengl {
|
|||||||
texture = ToBackend(textureView->GetTexture())->GetHandle();
|
texture = ToBackend(textureView->GetTexture())->GetHandle();
|
||||||
} else {
|
} else {
|
||||||
texture = device->GetCurrentTexture();
|
texture = device->GetCurrentTexture();
|
||||||
usingBackbuffer = true;
|
|
||||||
}
|
}
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + index,
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
|
||||||
|
GL_COLOR_ATTACHMENT0 + index,
|
||||||
GL_TEXTURE_2D, texture, 0);
|
GL_TEXTURE_2D, texture, 0);
|
||||||
}
|
}
|
||||||
// TODO(kainino@chromium.org): load depth attachment from subpass
|
if (info.depthStencilAttachmentSet) {
|
||||||
if (usingBackbuffer) {
|
uint32_t attachment = info.depthStencilAttachment;
|
||||||
GLuint texture = device->GetCurrentDepthTexture();
|
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
|
auto textureView = currentFramebuffer->GetTextureView(attachment);
|
||||||
GL_TEXTURE_2D, texture, 0);
|
GLuint texture = ToBackend(textureView->GetTexture())->GetHandle();
|
||||||
|
nxt::TextureFormat format = textureView->GetTexture()->GetFormat();
|
||||||
|
|
||||||
|
GLenum glAttachment = 0;
|
||||||
|
if (TextureFormatHasDepth(format)) {
|
||||||
|
if (TextureFormatHasStencil(format)) {
|
||||||
|
glAttachment = GL_DEPTH_STENCIL_ATTACHMENT;
|
||||||
|
} else {
|
||||||
|
glAttachment = GL_DEPTH_ATTACHMENT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
glAttachment = GL_STENCIL_ATTACHMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
|
||||||
|
glAttachment, GL_TEXTURE_2D, texture, 0);
|
||||||
|
// Load action
|
||||||
|
glClearStencil(0);
|
||||||
|
glClearDepth(1.0);
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -111,9 +111,7 @@ namespace opengl {
|
|||||||
void Device::HACKCLEAR() {
|
void Device::HACKCLEAR() {
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, backFBO);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, backFBO);
|
||||||
glClearColor(0, 0, 0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
glStencilMask(0xff);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
glClearStencil(0);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::InitBackbuffer() {
|
void Device::InitBackbuffer() {
|
||||||
@ -121,16 +119,10 @@ namespace opengl {
|
|||||||
glBindTexture(GL_TEXTURE_2D, backTexture);
|
glBindTexture(GL_TEXTURE_2D, backTexture);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 640, 480, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 640, 480, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||||
|
|
||||||
glGenTextures(1, &backDepthTexture);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, backDepthTexture);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 640, 480, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
|
|
||||||
|
|
||||||
glGenFramebuffers(1, &backFBO);
|
glGenFramebuffers(1, &backFBO);
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, backFBO);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, backFBO);
|
||||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||||
GL_TEXTURE_2D, backTexture, 0);
|
GL_TEXTURE_2D, backTexture, 0);
|
||||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
|
|
||||||
GL_TEXTURE_2D, backDepthTexture, 0);
|
|
||||||
|
|
||||||
HACKCLEAR();
|
HACKCLEAR();
|
||||||
}
|
}
|
||||||
@ -146,10 +138,6 @@ namespace opengl {
|
|||||||
return backTexture;
|
return backTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint Device::GetCurrentDepthTexture() {
|
|
||||||
return backDepthTexture;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind Group
|
// Bind Group
|
||||||
|
|
||||||
BindGroup::BindGroup(BindGroupBuilder* builder)
|
BindGroup::BindGroup(BindGroupBuilder* builder)
|
||||||
|
@ -103,12 +103,10 @@ namespace opengl {
|
|||||||
void InitBackbuffer();
|
void InitBackbuffer();
|
||||||
void CommitBackbuffer();
|
void CommitBackbuffer();
|
||||||
GLuint GetCurrentTexture();
|
GLuint GetCurrentTexture();
|
||||||
GLuint GetCurrentDepthTexture();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLuint backFBO = 0;
|
GLuint backFBO = 0;
|
||||||
GLuint backTexture = 0;
|
GLuint backTexture = 0;
|
||||||
GLuint backDepthTexture = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BindGroup : public BindGroupBase {
|
class BindGroup : public BindGroupBase {
|
||||||
|
@ -37,6 +37,8 @@ namespace opengl {
|
|||||||
switch (format) {
|
switch (format) {
|
||||||
case nxt::TextureFormat::R8G8B8A8Unorm:
|
case nxt::TextureFormat::R8G8B8A8Unorm:
|
||||||
return {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE};
|
return {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE};
|
||||||
|
case nxt::TextureFormat::D32FloatS8Uint:
|
||||||
|
return {GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV};
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ namespace backend {
|
|||||||
namespace d3d12 {
|
namespace d3d12 {
|
||||||
void Init(ComPtr<ID3D12Device> d3d12Device, nxtProcTable* procs, nxtDevice* device);
|
void Init(ComPtr<ID3D12Device> d3d12Device, nxtProcTable* procs, nxtDevice* device);
|
||||||
ComPtr<ID3D12CommandQueue> GetCommandQueue(nxtDevice device);
|
ComPtr<ID3D12CommandQueue> GetCommandQueue(nxtDevice device);
|
||||||
void SetNextTexture(nxtDevice device, ComPtr<ID3D12Resource> resource, ComPtr<ID3D12Resource> depthResource);
|
void SetNextTexture(nxtDevice device, ComPtr<ID3D12Resource> resource);
|
||||||
uint64_t GetSerial(const nxtDevice device);
|
uint64_t GetSerial(const nxtDevice device);
|
||||||
void NextSerial(nxtDevice device);
|
void NextSerial(nxtDevice device);
|
||||||
void ExecuteCommandLists(nxtDevice device, std::initializer_list<ID3D12CommandList*> commandLists);
|
void ExecuteCommandLists(nxtDevice device, std::initializer_list<ID3D12CommandList*> commandLists);
|
||||||
@ -101,43 +101,8 @@ namespace utils {
|
|||||||
));
|
));
|
||||||
ASSERT_SUCCESS(swapChain1.As(&swapChain));
|
ASSERT_SUCCESS(swapChain1.As(&swapChain));
|
||||||
|
|
||||||
// Create a render target and depth stencil resource for each frame.
|
|
||||||
{
|
|
||||||
D3D12_HEAP_PROPERTIES dsvHeapProperties;
|
|
||||||
dsvHeapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
|
||||||
dsvHeapProperties.CreationNodeMask = 0;
|
|
||||||
dsvHeapProperties.VisibleNodeMask = 0;
|
|
||||||
dsvHeapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
|
||||||
dsvHeapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
|
||||||
|
|
||||||
D3D12_RESOURCE_DESC dsvDesc;
|
|
||||||
dsvDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
|
||||||
dsvDesc.Alignment = 0;
|
|
||||||
dsvDesc.Width = width;
|
|
||||||
dsvDesc.Height = height;
|
|
||||||
dsvDesc.DepthOrArraySize = 1;
|
|
||||||
dsvDesc.MipLevels = 0;
|
|
||||||
dsvDesc.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
|
|
||||||
dsvDesc.SampleDesc.Count = 1;
|
|
||||||
dsvDesc.SampleDesc.Quality = 0;
|
|
||||||
dsvDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
|
||||||
dsvDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
|
|
||||||
|
|
||||||
D3D12_CLEAR_VALUE dsvClear;
|
|
||||||
dsvClear.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
|
|
||||||
dsvClear.DepthStencil.Depth = 1.0f;
|
|
||||||
dsvClear.DepthStencil.Stencil = 0;
|
|
||||||
|
|
||||||
for (uint32_t n = 0; n < kFrameCount; ++n) {
|
for (uint32_t n = 0; n < kFrameCount; ++n) {
|
||||||
ASSERT_SUCCESS(swapChain->GetBuffer(n, IID_PPV_ARGS(&renderTargetResources[n])));
|
ASSERT_SUCCESS(swapChain->GetBuffer(n, IID_PPV_ARGS(&renderTargetResources[n])));
|
||||||
ASSERT_SUCCESS(d3d12Device->CreateCommittedResource(
|
|
||||||
&dsvHeapProperties,
|
|
||||||
D3D12_HEAP_FLAG_NONE,
|
|
||||||
&dsvDesc,
|
|
||||||
D3D12_RESOURCE_STATE_DEPTH_WRITE,
|
|
||||||
&dsvClear,
|
|
||||||
IID_PPV_ARGS(&depthStencilResources[n])));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the initial render target and arbitrarily choose a "previous" render target that's different
|
// Get the initial render target and arbitrarily choose a "previous" render target that's different
|
||||||
@ -168,7 +133,7 @@ namespace utils {
|
|||||||
backend::d3d12::NextSerial(backendDevice);
|
backend::d3d12::NextSerial(backendDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
backend::d3d12::SetNextTexture(backendDevice, renderTargetResources[renderTargetIndex], depthStencilResources[renderTargetIndex]);
|
backend::d3d12::SetNextTexture(backendDevice, renderTargetResources[renderTargetIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapBuffers() override {
|
void SwapBuffers() override {
|
||||||
@ -217,7 +182,7 @@ namespace utils {
|
|||||||
lastSerialRenderTargetWasUsed[renderTargetIndex] = backend::d3d12::GetSerial(backendDevice);
|
lastSerialRenderTargetWasUsed[renderTargetIndex] = backend::d3d12::GetSerial(backendDevice);
|
||||||
|
|
||||||
// Tell the backend to render to the current render target
|
// Tell the backend to render to the current render target
|
||||||
backend::d3d12::SetNextTexture(backendDevice, renderTargetResources[renderTargetIndex], depthStencilResources[renderTargetIndex]);
|
backend::d3d12::SetNextTexture(backendDevice, renderTargetResources[renderTargetIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -232,7 +197,6 @@ namespace utils {
|
|||||||
ComPtr<ID3D12CommandQueue> commandQueue;
|
ComPtr<ID3D12CommandQueue> commandQueue;
|
||||||
ComPtr<IDXGISwapChain3> swapChain;
|
ComPtr<IDXGISwapChain3> swapChain;
|
||||||
ComPtr<ID3D12Resource> renderTargetResources[kFrameCount];
|
ComPtr<ID3D12Resource> renderTargetResources[kFrameCount];
|
||||||
ComPtr<ID3D12Resource> depthStencilResources[kFrameCount];
|
|
||||||
|
|
||||||
// Frame synchronization. Updated every frame
|
// Frame synchronization. Updated every frame
|
||||||
uint32_t renderTargetIndex;
|
uint32_t renderTargetIndex;
|
||||||
|
@ -88,15 +88,30 @@ namespace utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CreateDefaultRenderPass(const nxt::Device& device, nxt::RenderPass* renderPass, nxt::Framebuffer* framebuffer) {
|
void CreateDefaultRenderPass(const nxt::Device& device, nxt::RenderPass* renderPass, nxt::Framebuffer* framebuffer) {
|
||||||
|
auto depthStencilTexture = device.CreateTextureBuilder()
|
||||||
|
.SetDimension(nxt::TextureDimension::e2D)
|
||||||
|
.SetExtent(640, 480, 1)
|
||||||
|
.SetFormat(nxt::TextureFormat::D32FloatS8Uint)
|
||||||
|
.SetMipLevels(1)
|
||||||
|
.SetAllowedUsage(nxt::TextureUsageBit::OutputAttachment)
|
||||||
|
.GetResult();
|
||||||
|
depthStencilTexture.FreezeUsage(nxt::TextureUsageBit::OutputAttachment);
|
||||||
|
auto depthStencilView = depthStencilTexture.CreateTextureViewBuilder()
|
||||||
|
.GetResult();
|
||||||
|
|
||||||
*renderPass = device.CreateRenderPassBuilder()
|
*renderPass = device.CreateRenderPassBuilder()
|
||||||
.SetAttachmentCount(1)
|
.SetAttachmentCount(2)
|
||||||
.AttachmentSetFormat(0, nxt::TextureFormat::R8G8B8A8Unorm)
|
.AttachmentSetFormat(0, nxt::TextureFormat::R8G8B8A8Unorm)
|
||||||
|
.AttachmentSetFormat(1, nxt::TextureFormat::D32FloatS8Uint)
|
||||||
.SetSubpassCount(1)
|
.SetSubpassCount(1)
|
||||||
.SubpassSetColorAttachment(0, 0, 0)
|
.SubpassSetColorAttachment(0, 0, 0)
|
||||||
|
.SubpassSetDepthStencilAttachment(0, 1)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
*framebuffer = device.CreateFramebufferBuilder()
|
*framebuffer = device.CreateFramebufferBuilder()
|
||||||
.SetRenderPass(*renderPass)
|
.SetRenderPass(*renderPass)
|
||||||
.SetDimensions(640, 480)
|
.SetDimensions(640, 480)
|
||||||
|
// Attachment 0 is implicit until we add WSI
|
||||||
|
.SetAttachment(1, depthStencilView)
|
||||||
.GetResult();
|
.GetResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user