mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-04 13:41:42 +00:00
parent
28684d93ed
commit
fec8c58a97
@ -81,8 +81,10 @@ void frame() {
|
||||
{
|
||||
nxtCommandBufferBuilder builder = nxtDeviceCreateCommandBufferBuilder(device);
|
||||
nxtCommandBufferBuilderBeginRenderPass(builder, renderpass, framebuffer);
|
||||
nxtCommandBufferBuilderBeginRenderSubpass(builder);
|
||||
nxtCommandBufferBuilderSetPipeline(builder, pipeline);
|
||||
nxtCommandBufferBuilderDrawArrays(builder, 3, 1, 0, 0);
|
||||
nxtCommandBufferBuilderEndRenderSubpass(builder);
|
||||
nxtCommandBufferBuilderEndRenderPass(builder);
|
||||
commands = nxtCommandBufferBuilderGetResult(builder);
|
||||
nxtCommandBufferBuilderRelease(builder);
|
||||
|
@ -445,18 +445,7 @@ namespace {
|
||||
device = CreateCppNXTDevice();
|
||||
|
||||
queue = device.CreateQueueBuilder().GetResult();
|
||||
renderpass = device.CreateRenderPassBuilder()
|
||||
.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();
|
||||
utils::CreateDefaultRenderPass(device, &renderpass, &framebuffer);
|
||||
|
||||
initBuffers();
|
||||
initSamplers();
|
||||
|
12
next.json
12
next.json
@ -591,7 +591,7 @@
|
||||
"name": "set attachment",
|
||||
"args": [
|
||||
{"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": "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": {
|
||||
"category": "enum",
|
||||
"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": {
|
||||
|
@ -126,6 +126,10 @@ namespace backend {
|
||||
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;
|
||||
@ -147,4 +151,30 @@ namespace backend {
|
||||
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 {
|
||||
std::bitset<kMaxColorAttachments> colorAttachmentsSet;
|
||||
std::array<uint32_t, kMaxColorAttachments> colorAttachments;
|
||||
bool depthStencilAttachmentSet = false;
|
||||
uint32_t depthStencilAttachment = 0;
|
||||
};
|
||||
|
||||
uint32_t GetAttachmentCount() const;
|
||||
@ -64,6 +66,7 @@ namespace backend {
|
||||
void AttachmentSetFormat(uint32_t attachmentSlot, nxt::TextureFormat format);
|
||||
void SetSubpassCount(uint32_t subpassCount);
|
||||
void SubpassSetColorAttachment(uint32_t subpass, uint32_t outputAttachmentLocation, uint32_t attachmentSlot);
|
||||
void SubpassSetDepthStencilAttachment(uint32_t subpass, uint32_t attachmentSlot);
|
||||
|
||||
private:
|
||||
friend class RenderPassBase;
|
||||
|
@ -23,11 +23,36 @@ namespace backend {
|
||||
switch (format) {
|
||||
case nxt::TextureFormat::R8G8B8A8Unorm:
|
||||
return 4;
|
||||
case nxt::TextureFormat::D32FloatS8Uint:
|
||||
return 8;
|
||||
default:
|
||||
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(TextureBuilder* builder)
|
||||
@ -95,15 +120,6 @@ namespace backend {
|
||||
currentUsage = usage;
|
||||
}
|
||||
|
||||
bool TextureBase::IsDepthFormat(nxt::TextureFormat format) {
|
||||
switch (format) {
|
||||
case nxt::TextureFormat::R8G8B8A8Unorm:
|
||||
return false;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
void TextureBase::TransitionUsage(nxt::TextureUsageBit usage) {
|
||||
if (!IsTransitionPossible(usage)) {
|
||||
device->HandleError("Texture frozen or usage not allowed");
|
||||
|
@ -24,6 +24,8 @@
|
||||
namespace backend {
|
||||
|
||||
size_t TextureFormatPixelSize(nxt::TextureFormat format);
|
||||
bool TextureFormatHasDepth(nxt::TextureFormat format);
|
||||
bool TextureFormatHasStencil(nxt::TextureFormat format);
|
||||
|
||||
class TextureBase : public RefCounted {
|
||||
public:
|
||||
@ -43,8 +45,6 @@ namespace backend {
|
||||
bool IsTransitionPossible(nxt::TextureUsageBit usage) const;
|
||||
void UpdateUsageInternal(nxt::TextureUsageBit usage);
|
||||
|
||||
static bool IsDepthFormat(nxt::TextureFormat format);
|
||||
|
||||
DeviceBase* GetDevice();
|
||||
|
||||
// NXT API
|
||||
|
@ -204,12 +204,7 @@ namespace d3d12 {
|
||||
d3d12Location.PlacedFootprint.Footprint.Height = textureLocation.height;
|
||||
d3d12Location.PlacedFootprint.Footprint.Depth = textureLocation.depth;
|
||||
|
||||
uint32_t texelSize = 0;
|
||||
switch (texture->GetFormat()) {
|
||||
case nxt::TextureFormat::R8G8B8A8Unorm:
|
||||
texelSize = 4;
|
||||
break;
|
||||
}
|
||||
size_t texelSize = TextureFormatPixelSize(texture->GetFormat());
|
||||
uint32_t rowSize = textureLocation.width * texelSize;
|
||||
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();
|
||||
}
|
||||
|
||||
void SetNextTexture(nxtDevice device, ComPtr<ID3D12Resource> resource, ComPtr<ID3D12Resource> depthResource) {
|
||||
void SetNextTexture(nxtDevice device, ComPtr<ID3D12Resource> resource) {
|
||||
Device* backendDevice = reinterpret_cast<Device*>(device);
|
||||
backendDevice->SetNextTexture(resource, depthResource);
|
||||
backendDevice->SetNextTexture(resource);
|
||||
}
|
||||
|
||||
uint64_t GetSerial(const nxtDevice device) {
|
||||
@ -160,14 +160,10 @@ namespace d3d12 {
|
||||
return nextTexture;
|
||||
}
|
||||
|
||||
ComPtr<ID3D12Resource> Device::GetCurrentDepthTexture() {
|
||||
return nextDepthTexture;
|
||||
void Device::SetNextTexture(ComPtr<ID3D12Resource> resource) {
|
||||
nextTexture = resource;
|
||||
}
|
||||
|
||||
void Device::SetNextTexture(ComPtr<ID3D12Resource> resource, ComPtr<ID3D12Resource> depthResource) {
|
||||
nextTexture = resource;
|
||||
nextDepthTexture = depthResource;
|
||||
}
|
||||
|
||||
void Device::TickImpl() {
|
||||
// Perform cleanup operations to free unused objects
|
||||
|
@ -124,8 +124,7 @@ namespace d3d12 {
|
||||
ComPtr<ID3D12GraphicsCommandList> GetPendingCommandList();
|
||||
|
||||
ComPtr<ID3D12Resource> GetCurrentTexture();
|
||||
ComPtr<ID3D12Resource> GetCurrentDepthTexture();
|
||||
void SetNextTexture(ComPtr<ID3D12Resource> resource, ComPtr<ID3D12Resource> depthResource);
|
||||
void SetNextTexture(ComPtr<ID3D12Resource> resource);
|
||||
|
||||
uint64_t GetSerial() const;
|
||||
void NextSerial();
|
||||
@ -153,7 +152,6 @@ namespace d3d12 {
|
||||
} pendingCommands;
|
||||
|
||||
ComPtr<ID3D12Resource> nextTexture;
|
||||
ComPtr<ID3D12Resource> nextDepthTexture;
|
||||
};
|
||||
|
||||
class DepthStencilState : public DepthStencilStateBase {
|
||||
|
@ -23,73 +23,79 @@ namespace d3d12 {
|
||||
|
||||
Framebuffer::Framebuffer(Device* device, FramebufferBuilder* builder)
|
||||
: FramebufferBase(builder), device(device) {
|
||||
|
||||
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 rtvIndex = 0;
|
||||
|
||||
for (uint32_t attachment = 0; attachment < attachmentCount; ++attachment) {
|
||||
uint32_t rtvCount = 0, dsvCount = 0;
|
||||
attachmentHeapIndices.resize(renderPass->GetAttachmentCount());
|
||||
for (uint32_t attachment = 0; attachment < renderPass->GetAttachmentCount(); ++attachment) {
|
||||
auto* textureView = GetTextureView(attachment);
|
||||
if (textureView) {
|
||||
ComPtr<ID3D12Resource> texture = ToBackend(textureView->GetTexture())->GetD3D12Resource();
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvHeap.GetCPUHandle(rtvIndex++);
|
||||
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = ToBackend(textureView)->GetRTVDescriptor();
|
||||
|
||||
device->GetD3D12Device()->CreateRenderTargetView(texture.Get(), &rtvDesc, rtvHandle);
|
||||
if (!textureView) {
|
||||
// TODO(kainino@chromium.org): null=backbuffer hack
|
||||
attachmentHeapIndices[attachment] = rtvCount++;
|
||||
continue;
|
||||
}
|
||||
auto format = textureView->GetTexture()->GetFormat();
|
||||
if (TextureFormatHasDepth(format) || TextureFormatHasStencil(format)) {
|
||||
attachmentHeapIndices[attachment] = dsvCount++;
|
||||
} else {
|
||||
// TODO(enga@google.com) no attachment. This will use the backbuffer. Remove when this hack is removed
|
||||
usingBackbuffer = true;
|
||||
rtvIndex++;
|
||||
attachmentHeapIndices[attachment] = rtvCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(enga@google.com): load depth attachment from subpass
|
||||
if (usingBackbuffer) {
|
||||
dsvHeap = device->GetDescriptorHeapAllocator()->AllocateCPUHeap(D3D12_DESCRIPTOR_HEAP_TYPE_DSV, 1);
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = dsvHeap.GetCPUHandle(0);
|
||||
if (rtvCount) {
|
||||
rtvHeap = device->GetDescriptorHeapAllocator()->AllocateCPUHeap(
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_RTV, rtvCount);
|
||||
}
|
||||
if (dsvCount) {
|
||||
dsvHeap = device->GetDescriptorHeapAllocator()->AllocateCPUHeap(
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE_DSV, dsvCount);
|
||||
}
|
||||
|
||||
D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc;
|
||||
dsvDesc.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
|
||||
dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
|
||||
dsvDesc.Texture2D.MipSlice = 0;
|
||||
dsvDesc.Flags = D3D12_DSV_FLAG_NONE;
|
||||
for (uint32_t attachment = 0; attachment < renderPass->GetAttachmentCount(); ++attachment) {
|
||||
uint32_t heapIndex = attachmentHeapIndices[attachment];
|
||||
auto* textureView = GetTextureView(attachment);
|
||||
if (!textureView) {
|
||||
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) {
|
||||
const auto& subpassInfo = GetRenderPass()->GetSubpassInfo(subpassIndex);
|
||||
|
||||
bool usingBackbuffer = false; // HACK(enga@google.com): workaround for not having depth attachments
|
||||
|
||||
OMSetRenderTargetArgs args;
|
||||
args.numRTVs = 0;
|
||||
OMSetRenderTargetArgs args = {};
|
||||
|
||||
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];
|
||||
const auto& attachmentInfo = GetRenderPass()->GetAttachmentInfo(attachment);
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvHeap.GetCPUHandle(attachment);
|
||||
args.RTVs[args.numRTVs++] = rtvHandle;
|
||||
if (!GetTextureView(attachment)) {
|
||||
usingBackbuffer = true;
|
||||
|
||||
// TODO(kainino@chromium.org): null=backbuffer hack
|
||||
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
|
||||
rtvDesc.Format = D3D12TextureFormat(attachmentInfo.format);
|
||||
rtvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
|
||||
rtvDesc.Texture2D.MipSlice = 0;
|
||||
rtvDesc.Texture2D.PlaneSlice = 0;
|
||||
|
||||
device->GetD3D12Device()->CreateRenderTargetView(device->GetCurrentTexture().Get(), &rtvDesc, rtvHandle);
|
||||
}
|
||||
}
|
||||
|
||||
if (usingBackbuffer) {
|
||||
args.dsv = dsvHeap.GetCPUHandle(0);
|
||||
args.RTVs[args.numRTVs++] = rtvHandle;
|
||||
}
|
||||
if (subpassInfo.depthStencilAttachmentSet) {
|
||||
uint32_t heapIndex = attachmentHeapIndices[subpassInfo.depthStencilAttachment];
|
||||
args.dsv = dsvHeap.GetCPUHandle(heapIndex);
|
||||
}
|
||||
|
||||
return args;
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "backend/d3d12/d3d12_platform.h"
|
||||
#include "backend/d3d12/DescriptorHeapAllocator.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace backend {
|
||||
namespace d3d12 {
|
||||
|
||||
@ -29,9 +31,9 @@ namespace d3d12 {
|
||||
class Framebuffer : public FramebufferBase {
|
||||
public:
|
||||
struct OMSetRenderTargetArgs {
|
||||
unsigned int numRTVs;
|
||||
unsigned int numRTVs = 0;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE RTVs[kMaxColorAttachments] = {};
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE dsv = { 0 };
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE dsv = {};
|
||||
};
|
||||
|
||||
Framebuffer(Device* device, FramebufferBuilder* builder);
|
||||
@ -41,6 +43,9 @@ namespace d3d12 {
|
||||
Device* device;
|
||||
DescriptorHeapHandle rtvHeap;
|
||||
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;
|
||||
}
|
||||
if (usage & nxt::TextureUsageBit::OutputAttachment) {
|
||||
resourceState |= D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
if (TextureBase::IsDepthFormat(format)) {
|
||||
if (TextureFormatHasDepth(format) || TextureFormatHasStencil(format)) {
|
||||
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;
|
||||
}
|
||||
if (usage & nxt::TextureUsageBit::OutputAttachment) {
|
||||
flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||
if (TextureBase::IsDepthFormat(format)) {
|
||||
if (TextureFormatHasDepth(format) || TextureFormatHasStencil(format)) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -77,6 +81,8 @@ namespace d3d12 {
|
||||
switch (format) {
|
||||
case nxt::TextureFormat::R8G8B8A8Unorm:
|
||||
return DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
case nxt::TextureFormat::D32FloatS8Uint:
|
||||
return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -96,7 +102,7 @@ namespace d3d12 {
|
||||
resourceDescriptor.SampleDesc.Count = 1;
|
||||
resourceDescriptor.SampleDesc.Quality = 0;
|
||||
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()));
|
||||
}
|
||||
@ -167,5 +173,14 @@ namespace d3d12 {
|
||||
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;
|
||||
D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor();
|
||||
D3D12_DEPTH_STENCIL_VIEW_DESC GetDSVDescriptor();
|
||||
|
||||
private:
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
|
@ -86,7 +86,6 @@ namespace metal {
|
||||
const auto& info = currentRenderPass->GetSubpassInfo(subpass);
|
||||
|
||||
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) {
|
||||
uint32_t attachment = info.colorAttachments[index];
|
||||
|
||||
@ -98,18 +97,30 @@ namespace metal {
|
||||
texture = ToBackend(textureView->GetTexture())->GetMTLTexture();
|
||||
} else {
|
||||
texture = device->GetCurrentTexture();
|
||||
usingBackbuffer = true;
|
||||
}
|
||||
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].storeAction = MTLStoreActionStore;
|
||||
}
|
||||
// TODO(kainino@chromium.org): load depth attachment from subpass
|
||||
if (usingBackbuffer) {
|
||||
descriptor.depthAttachment.texture = device->GetCurrentDepthTexture();
|
||||
descriptor.depthAttachment.loadAction = MTLLoadActionLoad;
|
||||
descriptor.depthAttachment.storeAction = MTLStoreActionStore;
|
||||
if (info.depthStencilAttachmentSet) {
|
||||
uint32_t attachment = info.depthStencilAttachment;
|
||||
|
||||
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;
|
||||
}
|
||||
if (TextureFormatHasStencil(format)) {
|
||||
descriptor.stencilAttachment.texture = texture;
|
||||
descriptor.stencilAttachment.loadAction = MTLLoadActionClear;
|
||||
descriptor.stencilAttachment.clearStencil = 0;
|
||||
descriptor.stencilAttachment.storeAction = MTLStoreActionStore;
|
||||
}
|
||||
}
|
||||
|
||||
render = [commandBuffer renderCommandEncoderWithDescriptor:descriptor];
|
||||
|
@ -108,7 +108,6 @@ namespace metal {
|
||||
|
||||
id<MTLDevice> GetMTLDevice();
|
||||
id<MTLTexture> GetCurrentTexture();
|
||||
id<MTLTexture> GetCurrentDepthTexture();
|
||||
|
||||
id<MTLCommandBuffer> GetPendingCommandBuffer();
|
||||
void SubmitPendingCommandBuffer();
|
||||
@ -127,7 +126,6 @@ namespace metal {
|
||||
|
||||
id<CAMetalDrawable> currentDrawable = nil;
|
||||
id<MTLTexture> currentTexture = nil;
|
||||
id<MTLTexture> currentDepthTexture = nil;
|
||||
|
||||
Serial finishedCommandSerial = 0;
|
||||
Serial pendingCommandSerial = 1;
|
||||
|
@ -74,9 +74,6 @@ namespace metal {
|
||||
|
||||
[currentTexture release];
|
||||
currentTexture = nil;
|
||||
|
||||
[currentDepthTexture release];
|
||||
currentDepthTexture = nil;
|
||||
}
|
||||
|
||||
BindGroupBase* Device::CreateBindGroup(BindGroupBuilder* builder) {
|
||||
@ -146,32 +143,11 @@ namespace metal {
|
||||
currentTexture = drawable.texture;
|
||||
[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];
|
||||
passDescriptor.colorAttachments[0].texture = currentTexture;
|
||||
passDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
|
||||
passDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
|
||||
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];
|
||||
@ -195,10 +171,6 @@ namespace metal {
|
||||
return currentTexture;
|
||||
}
|
||||
|
||||
id<MTLTexture> Device::GetCurrentDepthTexture() {
|
||||
return currentDepthTexture;
|
||||
}
|
||||
|
||||
id<MTLCommandBuffer> Device::GetPendingCommandBuffer() {
|
||||
if (pendingCommands == nil) {
|
||||
pendingCommands = [commandQueue commandBuffer];
|
||||
|
@ -24,6 +24,8 @@ namespace metal {
|
||||
switch (format) {
|
||||
case nxt::TextureFormat::R8G8B8A8Unorm:
|
||||
return MTLPixelFormatRGBA8Unorm;
|
||||
case nxt::TextureFormat::D32FloatS8Uint:
|
||||
return MTLPixelFormatDepth32Float_Stencil8;
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,6 +67,7 @@ namespace metal {
|
||||
desc.depth = GetDepth();
|
||||
desc.mipmapLevelCount = GetNumMipLevels();
|
||||
desc.arrayLength = 1;
|
||||
desc.storageMode = MTLStorageModePrivate;
|
||||
|
||||
auto mtlDevice = ToBackend(builder->GetDevice())->GetMTLDevice();
|
||||
mtlTexture = [mtlDevice newTextureWithDescriptor:desc];
|
||||
|
@ -103,7 +103,6 @@ namespace opengl {
|
||||
auto* device = ToBackend(GetDevice());
|
||||
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) {
|
||||
uint32_t attachment = info.colorAttachments[index];
|
||||
|
||||
@ -115,16 +114,35 @@ namespace opengl {
|
||||
texture = ToBackend(textureView->GetTexture())->GetHandle();
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
// TODO(kainino@chromium.org): load depth attachment from subpass
|
||||
if (usingBackbuffer) {
|
||||
GLuint texture = device->GetCurrentDepthTexture();
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
|
||||
GL_TEXTURE_2D, texture, 0);
|
||||
if (info.depthStencilAttachmentSet) {
|
||||
uint32_t attachment = info.depthStencilAttachment;
|
||||
|
||||
auto textureView = currentFramebuffer->GetTextureView(attachment);
|
||||
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;
|
||||
|
@ -111,9 +111,7 @@ namespace opengl {
|
||||
void Device::HACKCLEAR() {
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, backFBO);
|
||||
glClearColor(0, 0, 0, 1);
|
||||
glStencilMask(0xff);
|
||||
glClearStencil(0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void Device::InitBackbuffer() {
|
||||
@ -121,16 +119,10 @@ namespace opengl {
|
||||
glBindTexture(GL_TEXTURE_2D, backTexture);
|
||||
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);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, backFBO);
|
||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D, backTexture, 0);
|
||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
|
||||
GL_TEXTURE_2D, backDepthTexture, 0);
|
||||
|
||||
HACKCLEAR();
|
||||
}
|
||||
@ -146,10 +138,6 @@ namespace opengl {
|
||||
return backTexture;
|
||||
}
|
||||
|
||||
GLuint Device::GetCurrentDepthTexture() {
|
||||
return backDepthTexture;
|
||||
}
|
||||
|
||||
// Bind Group
|
||||
|
||||
BindGroup::BindGroup(BindGroupBuilder* builder)
|
||||
|
@ -103,12 +103,10 @@ namespace opengl {
|
||||
void InitBackbuffer();
|
||||
void CommitBackbuffer();
|
||||
GLuint GetCurrentTexture();
|
||||
GLuint GetCurrentDepthTexture();
|
||||
|
||||
private:
|
||||
GLuint backFBO = 0;
|
||||
GLuint backTexture = 0;
|
||||
GLuint backDepthTexture = 0;
|
||||
};
|
||||
|
||||
class BindGroup : public BindGroupBase {
|
||||
|
@ -37,6 +37,8 @@ namespace opengl {
|
||||
switch (format) {
|
||||
case nxt::TextureFormat::R8G8B8A8Unorm:
|
||||
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:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ namespace backend {
|
||||
namespace d3d12 {
|
||||
void Init(ComPtr<ID3D12Device> d3d12Device, nxtProcTable* procs, 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);
|
||||
void NextSerial(nxtDevice device);
|
||||
void ExecuteCommandLists(nxtDevice device, std::initializer_list<ID3D12CommandList*> commandLists);
|
||||
@ -100,44 +100,9 @@ namespace utils {
|
||||
&swapChain1
|
||||
));
|
||||
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) {
|
||||
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])));
|
||||
}
|
||||
for (uint32_t n = 0; n < kFrameCount; ++n) {
|
||||
ASSERT_SUCCESS(swapChain->GetBuffer(n, IID_PPV_ARGS(&renderTargetResources[n])));
|
||||
}
|
||||
|
||||
// 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::SetNextTexture(backendDevice, renderTargetResources[renderTargetIndex], depthStencilResources[renderTargetIndex]);
|
||||
backend::d3d12::SetNextTexture(backendDevice, renderTargetResources[renderTargetIndex]);
|
||||
}
|
||||
|
||||
void SwapBuffers() override {
|
||||
@ -217,7 +182,7 @@ namespace utils {
|
||||
lastSerialRenderTargetWasUsed[renderTargetIndex] = backend::d3d12::GetSerial(backendDevice);
|
||||
|
||||
// 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:
|
||||
@ -232,7 +197,6 @@ namespace utils {
|
||||
ComPtr<ID3D12CommandQueue> commandQueue;
|
||||
ComPtr<IDXGISwapChain3> swapChain;
|
||||
ComPtr<ID3D12Resource> renderTargetResources[kFrameCount];
|
||||
ComPtr<ID3D12Resource> depthStencilResources[kFrameCount];
|
||||
|
||||
// Frame synchronization. Updated every frame
|
||||
uint32_t renderTargetIndex;
|
||||
|
@ -88,15 +88,30 @@ namespace utils {
|
||||
}
|
||||
|
||||
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()
|
||||
.SetAttachmentCount(1)
|
||||
.SetAttachmentCount(2)
|
||||
.AttachmentSetFormat(0, nxt::TextureFormat::R8G8B8A8Unorm)
|
||||
.AttachmentSetFormat(1, nxt::TextureFormat::D32FloatS8Uint)
|
||||
.SetSubpassCount(1)
|
||||
.SubpassSetColorAttachment(0, 0, 0)
|
||||
.SubpassSetDepthStencilAttachment(0, 1)
|
||||
.GetResult();
|
||||
*framebuffer = device.CreateFramebufferBuilder()
|
||||
.SetRenderPass(*renderPass)
|
||||
.SetDimensions(640, 480)
|
||||
// Attachment 0 is implicit until we add WSI
|
||||
.SetAttachment(1, depthStencilView)
|
||||
.GetResult();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user