Add RHI vertex and index buffer views
This commit is contained in:
@@ -88,6 +88,8 @@ public:
|
|||||||
RHIDescriptorPool* CreateDescriptorPool(const DescriptorPoolDesc& desc) override;
|
RHIDescriptorPool* CreateDescriptorPool(const DescriptorPoolDesc& desc) override;
|
||||||
RHIDescriptorSet* CreateDescriptorSet(RHIDescriptorPool* pool, const DescriptorSetLayoutDesc& layout) override;
|
RHIDescriptorSet* CreateDescriptorSet(RHIDescriptorPool* pool, const DescriptorSetLayoutDesc& layout) override;
|
||||||
|
|
||||||
|
RHIResourceView* CreateVertexBufferView(RHIBuffer* buffer, const ResourceViewDesc& desc) override;
|
||||||
|
RHIResourceView* CreateIndexBufferView(RHIBuffer* buffer, const ResourceViewDesc& desc) override;
|
||||||
RHIResourceView* CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) override;
|
RHIResourceView* CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) override;
|
||||||
RHIResourceView* CreateDepthStencilView(RHITexture* texture, const ResourceViewDesc& desc) override;
|
RHIResourceView* CreateDepthStencilView(RHITexture* texture, const ResourceViewDesc& desc) override;
|
||||||
RHIResourceView* CreateShaderResourceView(RHITexture* texture, const ResourceViewDesc& desc) override;
|
RHIResourceView* CreateShaderResourceView(RHITexture* texture, const ResourceViewDesc& desc) override;
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace XCEngine {
|
|||||||
namespace RHI {
|
namespace RHI {
|
||||||
|
|
||||||
class D3D12DescriptorHeap;
|
class D3D12DescriptorHeap;
|
||||||
|
class D3D12Buffer;
|
||||||
|
|
||||||
class D3D12ResourceView : public RHIResourceView {
|
class D3D12ResourceView : public RHIResourceView {
|
||||||
public:
|
public:
|
||||||
@@ -46,12 +47,18 @@ public:
|
|||||||
void InitializeAsConstantBuffer(ID3D12Device* device, ID3D12Resource* resource,
|
void InitializeAsConstantBuffer(ID3D12Device* device, ID3D12Resource* resource,
|
||||||
const D3D12_CONSTANT_BUFFER_VIEW_DESC* desc,
|
const D3D12_CONSTANT_BUFFER_VIEW_DESC* desc,
|
||||||
D3D12DescriptorHeap* heap, uint32_t slotIndex);
|
D3D12DescriptorHeap* heap, uint32_t slotIndex);
|
||||||
|
void InitializeAsVertexBuffer(D3D12Buffer* buffer, const ResourceViewDesc& desc);
|
||||||
|
void InitializeAsIndexBuffer(D3D12Buffer* buffer, const ResourceViewDesc& desc);
|
||||||
|
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE GetCPUHandle() const { return m_handle; }
|
D3D12_CPU_DESCRIPTOR_HANDLE GetCPUHandle() const { return m_handle; }
|
||||||
GPUDescriptorHandle GetGPUHandle() const;
|
GPUDescriptorHandle GetGPUHandle() const;
|
||||||
ID3D12Resource* GetResource() const { return m_resource; }
|
ID3D12Resource* GetResource() const { return m_resource; }
|
||||||
D3D12DescriptorHeap* GetHeap() const { return m_heap; }
|
D3D12DescriptorHeap* GetHeap() const { return m_heap; }
|
||||||
uint32_t GetSlotIndex() const { return m_slotIndex; }
|
uint32_t GetSlotIndex() const { return m_slotIndex; }
|
||||||
|
uint64_t GetBufferLocation() const { return m_bufferLocation; }
|
||||||
|
uint32_t GetBufferSize() const { return m_bufferSize; }
|
||||||
|
uint32_t GetBufferStride() const { return m_bufferStride; }
|
||||||
|
uint64_t GetBufferOffset() const { return m_bufferOffset; }
|
||||||
|
|
||||||
static D3D12_RENDER_TARGET_VIEW_DESC CreateRenderTargetDesc(Format format, D3D12_RTV_DIMENSION dimension);
|
static D3D12_RENDER_TARGET_VIEW_DESC CreateRenderTargetDesc(Format format, D3D12_RTV_DIMENSION dimension);
|
||||||
static D3D12_DEPTH_STENCIL_VIEW_DESC CreateDepthStencilDesc(Format format, D3D12_DSV_DIMENSION dimension);
|
static D3D12_DEPTH_STENCIL_VIEW_DESC CreateDepthStencilDesc(Format format, D3D12_DSV_DIMENSION dimension);
|
||||||
@@ -67,6 +74,10 @@ private:
|
|||||||
D3D12DescriptorHeap* m_heap;
|
D3D12DescriptorHeap* m_heap;
|
||||||
uint32_t m_slotIndex;
|
uint32_t m_slotIndex;
|
||||||
std::unique_ptr<D3D12DescriptorHeap> m_ownedHeap;
|
std::unique_ptr<D3D12DescriptorHeap> m_ownedHeap;
|
||||||
|
uint64_t m_bufferLocation;
|
||||||
|
uint64_t m_bufferOffset;
|
||||||
|
uint32_t m_bufferSize;
|
||||||
|
uint32_t m_bufferStride;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace RHI
|
} // namespace RHI
|
||||||
|
|||||||
@@ -59,6 +59,8 @@ public:
|
|||||||
RHIDescriptorPool* CreateDescriptorPool(const DescriptorPoolDesc& desc) override;
|
RHIDescriptorPool* CreateDescriptorPool(const DescriptorPoolDesc& desc) override;
|
||||||
RHIDescriptorSet* CreateDescriptorSet(RHIDescriptorPool* pool, const DescriptorSetLayoutDesc& layout) override;
|
RHIDescriptorSet* CreateDescriptorSet(RHIDescriptorPool* pool, const DescriptorSetLayoutDesc& layout) override;
|
||||||
|
|
||||||
|
RHIResourceView* CreateVertexBufferView(RHIBuffer* buffer, const ResourceViewDesc& desc) override;
|
||||||
|
RHIResourceView* CreateIndexBufferView(RHIBuffer* buffer, const ResourceViewDesc& desc) override;
|
||||||
RHIResourceView* CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) override;
|
RHIResourceView* CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) override;
|
||||||
RHIResourceView* CreateDepthStencilView(RHITexture* texture, const ResourceViewDesc& desc) override;
|
RHIResourceView* CreateDepthStencilView(RHITexture* texture, const ResourceViewDesc& desc) override;
|
||||||
RHIResourceView* CreateShaderResourceView(RHITexture* texture, const ResourceViewDesc& desc) override;
|
RHIResourceView* CreateShaderResourceView(RHITexture* texture, const ResourceViewDesc& desc) override;
|
||||||
|
|||||||
@@ -45,6 +45,12 @@ public:
|
|||||||
OpenGLBuffer* buffer,
|
OpenGLBuffer* buffer,
|
||||||
const ResourceViewDesc& desc,
|
const ResourceViewDesc& desc,
|
||||||
OpenGLUniformBufferManager* manager);
|
OpenGLUniformBufferManager* manager);
|
||||||
|
bool InitializeAsVertexBuffer(
|
||||||
|
OpenGLBuffer* buffer,
|
||||||
|
const ResourceViewDesc& desc);
|
||||||
|
bool InitializeAsIndexBuffer(
|
||||||
|
OpenGLBuffer* buffer,
|
||||||
|
const ResourceViewDesc& desc);
|
||||||
|
|
||||||
ResourceViewType GetViewType() const override { return m_viewType; }
|
ResourceViewType GetViewType() const override { return m_viewType; }
|
||||||
ResourceViewDimension GetDimension() const override { return m_dimension; }
|
ResourceViewDimension GetDimension() const override { return m_dimension; }
|
||||||
@@ -54,6 +60,9 @@ public:
|
|||||||
int32_t GetBindingPoint() const { return m_bindingPoint; }
|
int32_t GetBindingPoint() const { return m_bindingPoint; }
|
||||||
unsigned int GetTexture() const;
|
unsigned int GetTexture() const;
|
||||||
unsigned int GetBuffer() const;
|
unsigned int GetBuffer() const;
|
||||||
|
uint64_t GetBufferOffset() const { return m_bufferOffset; }
|
||||||
|
uint32_t GetBufferSize() const { return m_bufferSize; }
|
||||||
|
uint32_t GetBufferStride() const { return m_bufferStride; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ResourceViewType m_viewType;
|
ResourceViewType m_viewType;
|
||||||
@@ -67,6 +76,9 @@ private:
|
|||||||
OpenGLFramebuffer* m_framebuffer;
|
OpenGLFramebuffer* m_framebuffer;
|
||||||
OpenGLTextureUnitAllocator* m_textureUnitAllocator;
|
OpenGLTextureUnitAllocator* m_textureUnitAllocator;
|
||||||
OpenGLUniformBufferManager* m_uniformBufferManager;
|
OpenGLUniformBufferManager* m_uniformBufferManager;
|
||||||
|
uint64_t m_bufferOffset;
|
||||||
|
uint32_t m_bufferSize;
|
||||||
|
uint32_t m_bufferStride;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace RHI
|
} // namespace RHI
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ public:
|
|||||||
virtual RHIDescriptorPool* CreateDescriptorPool(const DescriptorPoolDesc& desc) = 0;
|
virtual RHIDescriptorPool* CreateDescriptorPool(const DescriptorPoolDesc& desc) = 0;
|
||||||
virtual RHIDescriptorSet* CreateDescriptorSet(RHIDescriptorPool* pool, const DescriptorSetLayoutDesc& layout) = 0;
|
virtual RHIDescriptorSet* CreateDescriptorSet(RHIDescriptorPool* pool, const DescriptorSetLayoutDesc& layout) = 0;
|
||||||
|
|
||||||
|
virtual RHIResourceView* CreateVertexBufferView(RHIBuffer* buffer, const ResourceViewDesc& desc) = 0;
|
||||||
|
virtual RHIResourceView* CreateIndexBufferView(RHIBuffer* buffer, const ResourceViewDesc& desc) = 0;
|
||||||
virtual RHIResourceView* CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) = 0;
|
virtual RHIResourceView* CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) = 0;
|
||||||
virtual RHIResourceView* CreateDepthStencilView(RHITexture* texture, const ResourceViewDesc& desc) = 0;
|
virtual RHIResourceView* CreateDepthStencilView(RHITexture* texture, const ResourceViewDesc& desc) = 0;
|
||||||
virtual RHIResourceView* CreateShaderResourceView(RHITexture* texture, const ResourceViewDesc& desc) = 0;
|
virtual RHIResourceView* CreateShaderResourceView(RHITexture* texture, const ResourceViewDesc& desc) = 0;
|
||||||
|
|||||||
@@ -278,6 +278,8 @@ enum class ResourceViewDimension : uint8_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum class ResourceViewType : uint8_t {
|
enum class ResourceViewType : uint8_t {
|
||||||
|
VertexBuffer,
|
||||||
|
IndexBuffer,
|
||||||
RenderTarget,
|
RenderTarget,
|
||||||
DepthStencil,
|
DepthStencil,
|
||||||
ShaderResource,
|
ShaderResource,
|
||||||
|
|||||||
@@ -408,9 +408,10 @@ void D3D12CommandList::SetVertexBuffers(uint32_t startSlot, uint32_t count, RHIR
|
|||||||
for (uint32_t i = 0; i < count; ++i) {
|
for (uint32_t i = 0; i < count; ++i) {
|
||||||
if (buffers[i] && buffers[i]->IsValid()) {
|
if (buffers[i] && buffers[i]->IsValid()) {
|
||||||
D3D12ResourceView* view = static_cast<D3D12ResourceView*>(buffers[i]);
|
D3D12ResourceView* view = static_cast<D3D12ResourceView*>(buffers[i]);
|
||||||
views[i].BufferLocation = view->GetResource()->GetGPUVirtualAddress() + offsets[i];
|
const uint32_t stride = strides[i] > 0 ? strides[i] : view->GetBufferStride();
|
||||||
views[i].StrideInBytes = strides[i];
|
views[i].BufferLocation = view->GetBufferLocation() + offsets[i];
|
||||||
views[i].SizeInBytes = static_cast<UINT>(view->GetResource()->GetDesc().Width) - static_cast<UINT>(offsets[i]);
|
views[i].StrideInBytes = stride;
|
||||||
|
views[i].SizeInBytes = view->GetBufferSize() > offsets[i] ? view->GetBufferSize() - static_cast<UINT>(offsets[i]) : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetVertexBuffersInternal(startSlot, count, views.data());
|
SetVertexBuffersInternal(startSlot, count, views.data());
|
||||||
@@ -431,7 +432,8 @@ void D3D12CommandList::SetVertexBuffer(uint32_t slot, ID3D12Resource* resource,
|
|||||||
void D3D12CommandList::SetIndexBuffer(RHIResourceView* buffer, uint64_t offset) {
|
void D3D12CommandList::SetIndexBuffer(RHIResourceView* buffer, uint64_t offset) {
|
||||||
if (!buffer || !buffer->IsValid()) return;
|
if (!buffer || !buffer->IsValid()) return;
|
||||||
D3D12ResourceView* view = static_cast<D3D12ResourceView*>(buffer);
|
D3D12ResourceView* view = static_cast<D3D12ResourceView*>(buffer);
|
||||||
SetIndexBufferInternal(view->GetResource(), offset, Format::R32_UInt);
|
const Format format = view->GetFormat() == Format::Unknown ? Format::R32_UInt : view->GetFormat();
|
||||||
|
SetIndexBufferInternal(view->GetResource(), view->GetBufferOffset() + offset, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12CommandList::SetIndexBuffer(ID3D12Resource* buffer, uint64_t offset, Format format) {
|
void D3D12CommandList::SetIndexBuffer(ID3D12Resource* buffer, uint64_t offset, Format format) {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "XCEngine/RHI/D3D12/D3D12Framebuffer.h"
|
#include "XCEngine/RHI/D3D12/D3D12Framebuffer.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#include <dxgidebug.h>
|
#include <dxgidebug.h>
|
||||||
@@ -27,6 +28,19 @@
|
|||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
namespace RHI {
|
namespace RHI {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
std::string NarrowAscii(const std::wstring& value) {
|
||||||
|
std::string result;
|
||||||
|
result.reserve(value.size());
|
||||||
|
for (wchar_t ch : value) {
|
||||||
|
result.push_back(static_cast<char>(ch));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
D3D12Device::D3D12Device()
|
D3D12Device::D3D12Device()
|
||||||
: m_isDeviceRemoved(false)
|
: m_isDeviceRemoved(false)
|
||||||
, m_initialized(false)
|
, m_initialized(false)
|
||||||
@@ -293,14 +307,16 @@ RHITexture* D3D12Device::CreateTexture(const TextureDesc& desc) {
|
|||||||
|
|
||||||
RHIShader* D3D12Device::CreateShader(const ShaderCompileDesc& desc) {
|
RHIShader* D3D12Device::CreateShader(const ShaderCompileDesc& desc) {
|
||||||
auto* shader = new D3D12Shader();
|
auto* shader = new D3D12Shader();
|
||||||
const char* entryPoint = desc.entryPoint.empty() ? nullptr : reinterpret_cast<const char*>(desc.entryPoint.c_str());
|
const std::string entryPoint = NarrowAscii(desc.entryPoint);
|
||||||
const char* profile = desc.profile.empty() ? nullptr : reinterpret_cast<const char*>(desc.profile.c_str());
|
const std::string profile = NarrowAscii(desc.profile);
|
||||||
|
const char* entryPointPtr = entryPoint.empty() ? nullptr : entryPoint.c_str();
|
||||||
|
const char* profilePtr = profile.empty() ? nullptr : profile.c_str();
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (!desc.source.empty()) {
|
if (!desc.source.empty()) {
|
||||||
success = shader->Compile(desc.source.data(), desc.source.size(), entryPoint, profile);
|
success = shader->Compile(desc.source.data(), desc.source.size(), entryPointPtr, profilePtr);
|
||||||
} else if (!desc.fileName.empty()) {
|
} else if (!desc.fileName.empty()) {
|
||||||
success = shader->CompileFromFile(desc.fileName.c_str(), entryPoint, profile);
|
success = shader->CompileFromFile(desc.fileName.c_str(), entryPointPtr, profilePtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
@@ -386,6 +402,36 @@ RHIFence* D3D12Device::CreateFence(const FenceDesc& desc) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RHIResourceView* D3D12Device::CreateVertexBufferView(RHIBuffer* buffer, const ResourceViewDesc& desc) {
|
||||||
|
if (!buffer) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* view = new D3D12ResourceView();
|
||||||
|
view->InitializeAsVertexBuffer(static_cast<D3D12Buffer*>(buffer), desc);
|
||||||
|
if (!view->IsValid()) {
|
||||||
|
delete view;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
RHIResourceView* D3D12Device::CreateIndexBufferView(RHIBuffer* buffer, const ResourceViewDesc& desc) {
|
||||||
|
if (!buffer) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* view = new D3D12ResourceView();
|
||||||
|
view->InitializeAsIndexBuffer(static_cast<D3D12Buffer*>(buffer), desc);
|
||||||
|
if (!view->IsValid()) {
|
||||||
|
delete view;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
RHISwapChain* D3D12Device::CreateSwapChain(const SwapChainDesc& desc, RHICommandQueue* presentQueue) {
|
RHISwapChain* D3D12Device::CreateSwapChain(const SwapChainDesc& desc, RHICommandQueue* presentQueue) {
|
||||||
if (presentQueue == nullptr) {
|
if (presentQueue == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "XCEngine/RHI/D3D12/D3D12ResourceView.h"
|
#include "XCEngine/RHI/D3D12/D3D12ResourceView.h"
|
||||||
|
#include "XCEngine/RHI/D3D12/D3D12Buffer.h"
|
||||||
#include "XCEngine/RHI/D3D12/D3D12DescriptorHeap.h"
|
#include "XCEngine/RHI/D3D12/D3D12DescriptorHeap.h"
|
||||||
|
|
||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
@@ -12,7 +13,11 @@ D3D12ResourceView::D3D12ResourceView()
|
|||||||
, m_resource(nullptr)
|
, m_resource(nullptr)
|
||||||
, m_heap(nullptr)
|
, m_heap(nullptr)
|
||||||
, m_slotIndex(0)
|
, m_slotIndex(0)
|
||||||
, m_ownedHeap(nullptr) {
|
, m_ownedHeap(nullptr)
|
||||||
|
, m_bufferLocation(0)
|
||||||
|
, m_bufferOffset(0)
|
||||||
|
, m_bufferSize(0)
|
||||||
|
, m_bufferStride(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D12ResourceView::~D3D12ResourceView() {
|
D3D12ResourceView::~D3D12ResourceView() {
|
||||||
@@ -28,14 +33,30 @@ void D3D12ResourceView::Shutdown() {
|
|||||||
}
|
}
|
||||||
m_heap = nullptr;
|
m_heap = nullptr;
|
||||||
m_slotIndex = 0;
|
m_slotIndex = 0;
|
||||||
|
m_bufferLocation = 0;
|
||||||
|
m_bufferOffset = 0;
|
||||||
|
m_bufferSize = 0;
|
||||||
|
m_bufferStride = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* D3D12ResourceView::GetNativeHandle() {
|
void* D3D12ResourceView::GetNativeHandle() {
|
||||||
return reinterpret_cast<void*>(m_handle.ptr);
|
switch (m_viewType) {
|
||||||
|
case ResourceViewType::VertexBuffer:
|
||||||
|
case ResourceViewType::IndexBuffer:
|
||||||
|
return m_resource;
|
||||||
|
default:
|
||||||
|
return reinterpret_cast<void*>(m_handle.ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool D3D12ResourceView::IsValid() const {
|
bool D3D12ResourceView::IsValid() const {
|
||||||
return m_handle.ptr != 0 && m_resource != nullptr;
|
switch (m_viewType) {
|
||||||
|
case ResourceViewType::VertexBuffer:
|
||||||
|
case ResourceViewType::IndexBuffer:
|
||||||
|
return m_resource != nullptr;
|
||||||
|
default:
|
||||||
|
return m_handle.ptr != 0 && m_resource != nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12ResourceView::InitializeAsRenderTarget(ID3D12Device* device, ID3D12Resource* resource,
|
void D3D12ResourceView::InitializeAsRenderTarget(ID3D12Device* device, ID3D12Resource* resource,
|
||||||
@@ -113,6 +134,36 @@ void D3D12ResourceView::InitializeAsConstantBuffer(ID3D12Device* device, ID3D12R
|
|||||||
device->CreateConstantBufferView(desc, m_handle);
|
device->CreateConstantBufferView(desc, m_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void D3D12ResourceView::InitializeAsVertexBuffer(D3D12Buffer* buffer, const ResourceViewDesc& desc) {
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_viewType = ResourceViewType::VertexBuffer;
|
||||||
|
m_format = Format::Unknown;
|
||||||
|
m_dimension = ResourceViewDimension::Buffer;
|
||||||
|
m_resource = buffer->GetResource();
|
||||||
|
m_bufferOffset = desc.bufferLocation;
|
||||||
|
m_bufferLocation = buffer->GetGPUVirtualAddress() + desc.bufferLocation;
|
||||||
|
m_bufferSize = static_cast<uint32_t>(buffer->GetSize() - desc.bufferLocation);
|
||||||
|
m_bufferStride = desc.structureByteStride > 0 ? desc.structureByteStride : buffer->GetStride();
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D12ResourceView::InitializeAsIndexBuffer(D3D12Buffer* buffer, const ResourceViewDesc& desc) {
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_viewType = ResourceViewType::IndexBuffer;
|
||||||
|
m_format = desc.format != 0 ? static_cast<Format>(desc.format) : Format::R32_UInt;
|
||||||
|
m_dimension = ResourceViewDimension::Buffer;
|
||||||
|
m_resource = buffer->GetResource();
|
||||||
|
m_bufferOffset = desc.bufferLocation;
|
||||||
|
m_bufferLocation = buffer->GetGPUVirtualAddress() + desc.bufferLocation;
|
||||||
|
m_bufferSize = static_cast<uint32_t>(buffer->GetSize() - desc.bufferLocation);
|
||||||
|
m_bufferStride = buffer->GetStride();
|
||||||
|
}
|
||||||
|
|
||||||
GPUDescriptorHandle D3D12ResourceView::GetGPUHandle() const {
|
GPUDescriptorHandle D3D12ResourceView::GetGPUHandle() const {
|
||||||
if (m_heap) {
|
if (m_heap) {
|
||||||
return m_heap->GetGPUDescriptorHandle(m_slotIndex);
|
return m_heap->GetGPUDescriptorHandle(m_slotIndex);
|
||||||
|
|||||||
@@ -641,7 +641,9 @@ void OpenGLCommandList::SetVertexBuffers(uint32_t startSlot, uint32_t count, RHI
|
|||||||
GLuint glBuffer = view->GetBuffer();
|
GLuint glBuffer = view->GetBuffer();
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, glBuffer);
|
glBindBuffer(GL_ARRAY_BUFFER, glBuffer);
|
||||||
glEnableVertexAttribArray(startSlot + i);
|
glEnableVertexAttribArray(startSlot + i);
|
||||||
glVertexAttribPointer(startSlot + i, strides[i] / sizeof(float), GL_FLOAT, GL_FALSE, strides[i], reinterpret_cast<void*>(static_cast<uintptr_t>(offsets[i])));
|
const uint32_t stride = strides[i] > 0 ? strides[i] : view->GetBufferStride();
|
||||||
|
const uint64_t offset = view->GetBufferOffset() + offsets[i];
|
||||||
|
glVertexAttribPointer(startSlot + i, stride / sizeof(float), GL_FLOAT, GL_FALSE, stride, reinterpret_cast<void*>(static_cast<uintptr_t>(offset)));
|
||||||
}
|
}
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -468,6 +468,34 @@ RHIDescriptorSet* OpenGLDevice::CreateDescriptorSet(RHIDescriptorPool* pool, con
|
|||||||
return pool->AllocateSet(layout);
|
return pool->AllocateSet(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RHIResourceView* OpenGLDevice::CreateVertexBufferView(RHIBuffer* buffer, const ResourceViewDesc& desc) {
|
||||||
|
if (!buffer) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* view = new OpenGLResourceView();
|
||||||
|
if (!view->InitializeAsVertexBuffer(static_cast<OpenGLBuffer*>(buffer), desc)) {
|
||||||
|
delete view;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
RHIResourceView* OpenGLDevice::CreateIndexBufferView(RHIBuffer* buffer, const ResourceViewDesc& desc) {
|
||||||
|
if (!buffer) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* view = new OpenGLResourceView();
|
||||||
|
if (!view->InitializeAsIndexBuffer(static_cast<OpenGLBuffer*>(buffer), desc)) {
|
||||||
|
delete view;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
RHIResourceView* OpenGLDevice::CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) {
|
RHIResourceView* OpenGLDevice::CreateRenderTargetView(RHITexture* texture, const ResourceViewDesc& desc) {
|
||||||
if (!texture) {
|
if (!texture) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -21,7 +21,10 @@ OpenGLResourceView::OpenGLResourceView()
|
|||||||
, m_buffer(nullptr)
|
, m_buffer(nullptr)
|
||||||
, m_framebuffer(nullptr)
|
, m_framebuffer(nullptr)
|
||||||
, m_textureUnitAllocator(nullptr)
|
, m_textureUnitAllocator(nullptr)
|
||||||
, m_uniformBufferManager(nullptr) {
|
, m_uniformBufferManager(nullptr)
|
||||||
|
, m_bufferOffset(0)
|
||||||
|
, m_bufferSize(0)
|
||||||
|
, m_bufferStride(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLResourceView::~OpenGLResourceView() {
|
OpenGLResourceView::~OpenGLResourceView() {
|
||||||
@@ -47,10 +50,16 @@ void OpenGLResourceView::Shutdown() {
|
|||||||
m_framebufferID = 0;
|
m_framebufferID = 0;
|
||||||
m_texture = nullptr;
|
m_texture = nullptr;
|
||||||
m_buffer = nullptr;
|
m_buffer = nullptr;
|
||||||
|
m_bufferOffset = 0;
|
||||||
|
m_bufferSize = 0;
|
||||||
|
m_bufferStride = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* OpenGLResourceView::GetNativeHandle() {
|
void* OpenGLResourceView::GetNativeHandle() {
|
||||||
switch (m_viewType) {
|
switch (m_viewType) {
|
||||||
|
case ResourceViewType::VertexBuffer:
|
||||||
|
case ResourceViewType::IndexBuffer:
|
||||||
|
return reinterpret_cast<void*>(static_cast<uintptr_t>(m_buffer ? m_buffer->GetID() : 0));
|
||||||
case ResourceViewType::RenderTarget:
|
case ResourceViewType::RenderTarget:
|
||||||
case ResourceViewType::DepthStencil:
|
case ResourceViewType::DepthStencil:
|
||||||
return reinterpret_cast<void*>(static_cast<uintptr_t>(m_framebufferID));
|
return reinterpret_cast<void*>(static_cast<uintptr_t>(m_framebufferID));
|
||||||
@@ -66,6 +75,9 @@ void* OpenGLResourceView::GetNativeHandle() {
|
|||||||
|
|
||||||
bool OpenGLResourceView::IsValid() const {
|
bool OpenGLResourceView::IsValid() const {
|
||||||
switch (m_viewType) {
|
switch (m_viewType) {
|
||||||
|
case ResourceViewType::VertexBuffer:
|
||||||
|
case ResourceViewType::IndexBuffer:
|
||||||
|
return m_buffer != nullptr && m_buffer->GetID() != 0;
|
||||||
case ResourceViewType::RenderTarget:
|
case ResourceViewType::RenderTarget:
|
||||||
case ResourceViewType::DepthStencil:
|
case ResourceViewType::DepthStencil:
|
||||||
return m_framebufferID != 0;
|
return m_framebufferID != 0;
|
||||||
@@ -186,6 +198,40 @@ bool OpenGLResourceView::InitializeAsConstantBuffer(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OpenGLResourceView::InitializeAsVertexBuffer(
|
||||||
|
OpenGLBuffer* buffer,
|
||||||
|
const ResourceViewDesc& desc) {
|
||||||
|
if (!buffer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_viewType = ResourceViewType::VertexBuffer;
|
||||||
|
m_format = Format::Unknown;
|
||||||
|
m_dimension = ResourceViewDimension::Buffer;
|
||||||
|
m_buffer = buffer;
|
||||||
|
m_bufferOffset = desc.bufferLocation;
|
||||||
|
m_bufferSize = static_cast<uint32_t>(buffer->GetSize());
|
||||||
|
m_bufferStride = desc.structureByteStride > 0 ? desc.structureByteStride : buffer->GetStride();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenGLResourceView::InitializeAsIndexBuffer(
|
||||||
|
OpenGLBuffer* buffer,
|
||||||
|
const ResourceViewDesc& desc) {
|
||||||
|
if (!buffer) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_viewType = ResourceViewType::IndexBuffer;
|
||||||
|
m_format = desc.format != 0 ? static_cast<Format>(desc.format) : Format::R32_UInt;
|
||||||
|
m_dimension = ResourceViewDimension::Buffer;
|
||||||
|
m_buffer = buffer;
|
||||||
|
m_bufferOffset = desc.bufferLocation;
|
||||||
|
m_bufferSize = static_cast<uint32_t>(buffer->GetSize());
|
||||||
|
m_bufferStride = buffer->GetStride();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int OpenGLResourceView::GetFramebuffer() const {
|
unsigned int OpenGLResourceView::GetFramebuffer() const {
|
||||||
return m_framebuffer ? m_framebuffer->GetFramebuffer() : 0;
|
return m_framebuffer ? m_framebuffer->GetFramebuffer() : 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,6 +144,73 @@ TEST_P(RHITestFixture, CommandList_DrawIndexed) {
|
|||||||
delete cmdList;
|
delete cmdList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, CommandList_SetVertexBuffers_WithRealView) {
|
||||||
|
BufferDesc bufferDesc = {};
|
||||||
|
bufferDesc.size = 256;
|
||||||
|
bufferDesc.stride = 32;
|
||||||
|
bufferDesc.bufferType = static_cast<uint32_t>(BufferType::Vertex);
|
||||||
|
|
||||||
|
RHIBuffer* buffer = GetDevice()->CreateBuffer(bufferDesc);
|
||||||
|
ASSERT_NE(buffer, nullptr);
|
||||||
|
|
||||||
|
ResourceViewDesc viewDesc = {};
|
||||||
|
viewDesc.dimension = ResourceViewDimension::Buffer;
|
||||||
|
viewDesc.structureByteStride = 32;
|
||||||
|
RHIResourceView* vbv = GetDevice()->CreateVertexBufferView(buffer, viewDesc);
|
||||||
|
ASSERT_NE(vbv, nullptr);
|
||||||
|
|
||||||
|
CommandListDesc cmdDesc = {};
|
||||||
|
cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct);
|
||||||
|
RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc);
|
||||||
|
ASSERT_NE(cmdList, nullptr);
|
||||||
|
|
||||||
|
uint64_t offsets[] = { 0 };
|
||||||
|
uint32_t strides[] = { 32 };
|
||||||
|
|
||||||
|
cmdList->Reset();
|
||||||
|
cmdList->SetVertexBuffers(0, 1, &vbv, offsets, strides);
|
||||||
|
cmdList->Close();
|
||||||
|
|
||||||
|
cmdList->Shutdown();
|
||||||
|
delete cmdList;
|
||||||
|
vbv->Shutdown();
|
||||||
|
delete vbv;
|
||||||
|
buffer->Shutdown();
|
||||||
|
delete buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, CommandList_SetIndexBuffer_WithRealView) {
|
||||||
|
BufferDesc bufferDesc = {};
|
||||||
|
bufferDesc.size = 256;
|
||||||
|
bufferDesc.stride = sizeof(uint32_t);
|
||||||
|
bufferDesc.bufferType = static_cast<uint32_t>(BufferType::Index);
|
||||||
|
|
||||||
|
RHIBuffer* buffer = GetDevice()->CreateBuffer(bufferDesc);
|
||||||
|
ASSERT_NE(buffer, nullptr);
|
||||||
|
|
||||||
|
ResourceViewDesc viewDesc = {};
|
||||||
|
viewDesc.dimension = ResourceViewDimension::Buffer;
|
||||||
|
viewDesc.format = static_cast<uint32_t>(Format::R32_UInt);
|
||||||
|
RHIResourceView* ibv = GetDevice()->CreateIndexBufferView(buffer, viewDesc);
|
||||||
|
ASSERT_NE(ibv, nullptr);
|
||||||
|
|
||||||
|
CommandListDesc cmdDesc = {};
|
||||||
|
cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct);
|
||||||
|
RHICommandList* cmdList = GetDevice()->CreateCommandList(cmdDesc);
|
||||||
|
ASSERT_NE(cmdList, nullptr);
|
||||||
|
|
||||||
|
cmdList->Reset();
|
||||||
|
cmdList->SetIndexBuffer(ibv, 0);
|
||||||
|
cmdList->Close();
|
||||||
|
|
||||||
|
cmdList->Shutdown();
|
||||||
|
delete cmdList;
|
||||||
|
ibv->Shutdown();
|
||||||
|
delete ibv;
|
||||||
|
buffer->Shutdown();
|
||||||
|
delete buffer;
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(RHITestFixture, CommandList_SetStencilRef) {
|
TEST_P(RHITestFixture, CommandList_SetStencilRef) {
|
||||||
CommandListDesc cmdDesc = {};
|
CommandListDesc cmdDesc = {};
|
||||||
cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct);
|
cmdDesc.commandListType = static_cast<uint32_t>(CommandQueueType::Direct);
|
||||||
@@ -454,4 +521,3 @@ TEST_P(RHITestFixture, CommandList_SetShader) {
|
|||||||
shader->Shutdown();
|
shader->Shutdown();
|
||||||
delete shader;
|
delete shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "fixtures/RHITestFixture.h"
|
#include "fixtures/RHITestFixture.h"
|
||||||
|
#include "XCEngine/RHI/RHIBuffer.h"
|
||||||
#include "XCEngine/RHI/RHIResourceView.h"
|
#include "XCEngine/RHI/RHIResourceView.h"
|
||||||
#include "XCEngine/RHI/RHITexture.h"
|
#include "XCEngine/RHI/RHITexture.h"
|
||||||
|
|
||||||
@@ -121,6 +122,56 @@ TEST_P(RHITestFixture, Device_CreateUnorderedAccessView) {
|
|||||||
delete texture;
|
delete texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Device_CreateVertexBufferView) {
|
||||||
|
BufferDesc bufferDesc = {};
|
||||||
|
bufferDesc.size = 256;
|
||||||
|
bufferDesc.stride = 32;
|
||||||
|
bufferDesc.bufferType = static_cast<uint32_t>(BufferType::Vertex);
|
||||||
|
|
||||||
|
RHIBuffer* buffer = GetDevice()->CreateBuffer(bufferDesc);
|
||||||
|
ASSERT_NE(buffer, nullptr);
|
||||||
|
|
||||||
|
ResourceViewDesc viewDesc = {};
|
||||||
|
viewDesc.dimension = ResourceViewDimension::Buffer;
|
||||||
|
viewDesc.structureByteStride = 32;
|
||||||
|
|
||||||
|
RHIResourceView* vbv = GetDevice()->CreateVertexBufferView(buffer, viewDesc);
|
||||||
|
ASSERT_NE(vbv, nullptr);
|
||||||
|
EXPECT_TRUE(vbv->IsValid());
|
||||||
|
EXPECT_EQ(vbv->GetViewType(), ResourceViewType::VertexBuffer);
|
||||||
|
EXPECT_EQ(vbv->GetDimension(), ResourceViewDimension::Buffer);
|
||||||
|
|
||||||
|
vbv->Shutdown();
|
||||||
|
delete vbv;
|
||||||
|
buffer->Shutdown();
|
||||||
|
delete buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, Device_CreateIndexBufferView) {
|
||||||
|
BufferDesc bufferDesc = {};
|
||||||
|
bufferDesc.size = 256;
|
||||||
|
bufferDesc.stride = sizeof(uint32_t);
|
||||||
|
bufferDesc.bufferType = static_cast<uint32_t>(BufferType::Index);
|
||||||
|
|
||||||
|
RHIBuffer* buffer = GetDevice()->CreateBuffer(bufferDesc);
|
||||||
|
ASSERT_NE(buffer, nullptr);
|
||||||
|
|
||||||
|
ResourceViewDesc viewDesc = {};
|
||||||
|
viewDesc.dimension = ResourceViewDimension::Buffer;
|
||||||
|
viewDesc.format = static_cast<uint32_t>(Format::R32_UInt);
|
||||||
|
|
||||||
|
RHIResourceView* ibv = GetDevice()->CreateIndexBufferView(buffer, viewDesc);
|
||||||
|
ASSERT_NE(ibv, nullptr);
|
||||||
|
EXPECT_TRUE(ibv->IsValid());
|
||||||
|
EXPECT_EQ(ibv->GetViewType(), ResourceViewType::IndexBuffer);
|
||||||
|
EXPECT_EQ(ibv->GetDimension(), ResourceViewDimension::Buffer);
|
||||||
|
|
||||||
|
ibv->Shutdown();
|
||||||
|
delete ibv;
|
||||||
|
buffer->Shutdown();
|
||||||
|
delete buffer;
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(RHITestFixture, Device_CreateRenderTargetView_Multiple) {
|
TEST_P(RHITestFixture, Device_CreateRenderTargetView_Multiple) {
|
||||||
TextureDesc texDesc = {};
|
TextureDesc texDesc = {};
|
||||||
texDesc.width = 256;
|
texDesc.width = 256;
|
||||||
|
|||||||
Reference in New Issue
Block a user