[D3D12] Non-indexed triangle fans and resource creation refactoring
This commit is contained in:
parent
d1f185c744
commit
5be78ab369
|
@ -442,23 +442,12 @@ ID3D12Resource* D3D12CommandProcessor::RequestScratchGPUBuffer(
|
||||||
auto context = GetD3D12Context();
|
auto context = GetD3D12Context();
|
||||||
auto device = context->GetD3D12Provider()->GetDevice();
|
auto device = context->GetD3D12Provider()->GetDevice();
|
||||||
D3D12_RESOURCE_DESC buffer_desc;
|
D3D12_RESOURCE_DESC buffer_desc;
|
||||||
buffer_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
ui::d3d12::util::FillBufferResourceDesc(
|
||||||
buffer_desc.Alignment = 0;
|
buffer_desc, size, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
|
||||||
buffer_desc.Width = size;
|
|
||||||
buffer_desc.Height = 1;
|
|
||||||
buffer_desc.DepthOrArraySize = 1;
|
|
||||||
buffer_desc.MipLevels = 1;
|
|
||||||
buffer_desc.Format = DXGI_FORMAT_UNKNOWN;
|
|
||||||
buffer_desc.SampleDesc.Count = 1;
|
|
||||||
buffer_desc.SampleDesc.Quality = 0;
|
|
||||||
buffer_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
|
||||||
buffer_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
|
||||||
D3D12_HEAP_PROPERTIES heap_properties = {};
|
|
||||||
heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
|
||||||
ID3D12Resource* buffer;
|
ID3D12Resource* buffer;
|
||||||
if (FAILED(device->CreateCommittedResource(
|
if (FAILED(device->CreateCommittedResource(
|
||||||
&heap_properties, D3D12_HEAP_FLAG_NONE, &buffer_desc, state, nullptr,
|
&ui::d3d12::util::kHeapPropertiesDefault, D3D12_HEAP_FLAG_NONE,
|
||||||
IID_PPV_ARGS(&buffer)))) {
|
&buffer_desc, state, nullptr, IID_PPV_ARGS(&buffer)))) {
|
||||||
XELOGE("Failed to create a %u MB scratch GPU buffer", size >> 20);
|
XELOGE("Failed to create a %u MB scratch GPU buffer", size >> 20);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -624,11 +613,12 @@ bool D3D12CommandProcessor::SetupContext() {
|
||||||
}
|
}
|
||||||
|
|
||||||
primitive_converter_ = std::make_unique<PrimitiveConverter>(
|
primitive_converter_ = std::make_unique<PrimitiveConverter>(
|
||||||
context, register_file_, memory_, shared_memory_.get());
|
this, register_file_, memory_, shared_memory_.get());
|
||||||
primitive_converter_->Initialize();
|
if (!primitive_converter_->Initialize()) {
|
||||||
|
XELOGE("Failed to initialize the geometric primitive converter");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
D3D12_HEAP_PROPERTIES swap_texture_heap_properties = {};
|
|
||||||
swap_texture_heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
|
||||||
D3D12_RESOURCE_DESC swap_texture_desc;
|
D3D12_RESOURCE_DESC swap_texture_desc;
|
||||||
swap_texture_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
swap_texture_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||||
swap_texture_desc.Alignment = 0;
|
swap_texture_desc.Alignment = 0;
|
||||||
|
@ -643,7 +633,7 @@ bool D3D12CommandProcessor::SetupContext() {
|
||||||
swap_texture_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
swap_texture_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||||
// Can be sampled at any time, switch to render target when needed, then back.
|
// Can be sampled at any time, switch to render target when needed, then back.
|
||||||
if (FAILED(device->CreateCommittedResource(
|
if (FAILED(device->CreateCommittedResource(
|
||||||
&swap_texture_heap_properties, D3D12_HEAP_FLAG_NONE,
|
&ui::d3d12::util::kHeapPropertiesDefault, D3D12_HEAP_FLAG_NONE,
|
||||||
&swap_texture_desc, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
&swap_texture_desc, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
|
||||||
nullptr, IID_PPV_ARGS(&swap_texture_)))) {
|
nullptr, IID_PPV_ARGS(&swap_texture_)))) {
|
||||||
XELOGE("Failed to create the command processor front buffer");
|
XELOGE("Failed to create the command processor front buffer");
|
||||||
|
@ -1055,10 +1045,9 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
||||||
uint32_t converted_index_count;
|
uint32_t converted_index_count;
|
||||||
PrimitiveConverter::ConversionResult conversion_result =
|
PrimitiveConverter::ConversionResult conversion_result =
|
||||||
primitive_converter_->ConvertPrimitives(
|
primitive_converter_->ConvertPrimitives(
|
||||||
primitive_type, index_buffer_info->guest_base,
|
primitive_type, index_buffer_info->guest_base, index_count,
|
||||||
index_buffer_info->count, index_buffer_info->format,
|
index_buffer_info->format, index_buffer_info->endianness,
|
||||||
index_buffer_info->endianness, index_buffer_view.BufferLocation,
|
index_buffer_view.BufferLocation, converted_index_count);
|
||||||
converted_index_count);
|
|
||||||
if (conversion_result == PrimitiveConverter::ConversionResult::kFailed) {
|
if (conversion_result == PrimitiveConverter::ConversionResult::kFailed) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1068,6 +1057,7 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
||||||
}
|
}
|
||||||
if (conversion_result == PrimitiveConverter::ConversionResult::kConverted) {
|
if (conversion_result == PrimitiveConverter::ConversionResult::kConverted) {
|
||||||
index_buffer_view.SizeInBytes = converted_index_count * index_size;
|
index_buffer_view.SizeInBytes = converted_index_count * index_size;
|
||||||
|
index_count = converted_index_count;
|
||||||
} else {
|
} else {
|
||||||
uint32_t index_buffer_size = index_buffer_info->count * index_size;
|
uint32_t index_buffer_size = index_buffer_info->count * index_size;
|
||||||
shared_memory_->RequestRange(index_base, index_buffer_size);
|
shared_memory_->RequestRange(index_base, index_buffer_size);
|
||||||
|
@ -1080,12 +1070,24 @@ bool D3D12CommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
||||||
SubmitBarriers();
|
SubmitBarriers();
|
||||||
command_list->DrawIndexedInstanced(index_count, 1, 0, 0, 0);
|
command_list->DrawIndexedInstanced(index_count, 1, 0, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
// TODO(Triang3l): Get a static index buffer for unsupported primitive types
|
// Check if need to draw using a conversion index buffer.
|
||||||
// from the primitive converter.
|
uint32_t converted_index_count;
|
||||||
|
D3D12_GPU_VIRTUAL_ADDRESS conversion_gpu_address =
|
||||||
|
primitive_converter_->GetStaticIndexBuffer(primitive_type, index_count,
|
||||||
|
converted_index_count);
|
||||||
shared_memory_->UseForReading();
|
shared_memory_->UseForReading();
|
||||||
SubmitBarriers();
|
SubmitBarriers();
|
||||||
|
if (conversion_gpu_address) {
|
||||||
|
D3D12_INDEX_BUFFER_VIEW index_buffer_view;
|
||||||
|
index_buffer_view.BufferLocation = conversion_gpu_address;
|
||||||
|
index_buffer_view.SizeInBytes = converted_index_count * sizeof(uint16_t);
|
||||||
|
index_buffer_view.Format = DXGI_FORMAT_R16_UINT;
|
||||||
|
command_list->IASetIndexBuffer(&index_buffer_view);
|
||||||
|
command_list->DrawIndexedInstanced(converted_index_count, 1, 0, 0, 0);
|
||||||
|
} else {
|
||||||
command_list->DrawInstanced(index_count, 1, 0, 0);
|
command_list->DrawInstanced(index_count, 1, 0, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1164,7 +1166,7 @@ bool D3D12CommandProcessor::BeginFrame() {
|
||||||
|
|
||||||
render_target_cache_->BeginFrame();
|
render_target_cache_->BeginFrame();
|
||||||
|
|
||||||
primitive_converter_->BeginFrame(GetCurrentCommandList());
|
primitive_converter_->BeginFrame();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,40 +9,123 @@
|
||||||
|
|
||||||
#include "xenia/gpu/d3d12/primitive_converter.h"
|
#include "xenia/gpu/d3d12/primitive_converter.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "xenia/base/assert.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/math.h"
|
#include "xenia/base/math.h"
|
||||||
#include "xenia/base/platform.h"
|
#include "xenia/base/platform.h"
|
||||||
|
#include "xenia/gpu/d3d12/d3d12_command_processor.h"
|
||||||
|
#include "xenia/ui/d3d12/d3d12_util.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
namespace d3d12 {
|
namespace d3d12 {
|
||||||
|
|
||||||
PrimitiveConverter::PrimitiveConverter(ui::d3d12::D3D12Context* context,
|
PrimitiveConverter::PrimitiveConverter(D3D12CommandProcessor* command_processor,
|
||||||
RegisterFile* register_file,
|
RegisterFile* register_file,
|
||||||
Memory* memory,
|
Memory* memory,
|
||||||
SharedMemory* shared_memory)
|
SharedMemory* shared_memory)
|
||||||
: context_(context),
|
: command_processor_(command_processor),
|
||||||
register_file_(register_file),
|
register_file_(register_file),
|
||||||
memory_(memory),
|
memory_(memory),
|
||||||
shared_memory_(shared_memory) {}
|
shared_memory_(shared_memory) {}
|
||||||
|
|
||||||
PrimitiveConverter::~PrimitiveConverter() { Shutdown(); }
|
PrimitiveConverter::~PrimitiveConverter() { Shutdown(); }
|
||||||
|
|
||||||
void PrimitiveConverter::Initialize() {
|
bool PrimitiveConverter::Initialize() {
|
||||||
|
auto context = command_processor_->GetD3D12Context();
|
||||||
|
auto device = context->GetD3D12Provider()->GetDevice();
|
||||||
|
|
||||||
// There can be at most 65535 indices in a Xenos draw call, but they can be up
|
// There can be at most 65535 indices in a Xenos draw call, but they can be up
|
||||||
// to 4 bytes large, and conversion can add more indices (almost triple the
|
// to 4 bytes large, and conversion can add more indices (almost triple the
|
||||||
// count for triangle strips, for instance).
|
// count for triangle strips, for instance).
|
||||||
buffer_pool_ =
|
buffer_pool_ =
|
||||||
std::make_unique<ui::d3d12::UploadBufferPool>(context_, 4 * 1024 * 1024);
|
std::make_unique<ui::d3d12::UploadBufferPool>(context, 4 * 1024 * 1024);
|
||||||
|
|
||||||
|
// Create the static index buffer for non-indexed drawing.
|
||||||
|
D3D12_RESOURCE_DESC static_ib_desc;
|
||||||
|
ui::d3d12::util::FillBufferResourceDesc(
|
||||||
|
static_ib_desc, kStaticIBTotalCount * sizeof(uint16_t),
|
||||||
|
D3D12_RESOURCE_FLAG_NONE);
|
||||||
|
if (FAILED(device->CreateCommittedResource(
|
||||||
|
&ui::d3d12::util::kHeapPropertiesUpload, D3D12_HEAP_FLAG_NONE,
|
||||||
|
&static_ib_desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr,
|
||||||
|
IID_PPV_ARGS(&static_ib_upload_)))) {
|
||||||
|
XELOGE(
|
||||||
|
"Failed to create the upload buffer for the primitive conversion "
|
||||||
|
"static index buffer");
|
||||||
|
Shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
D3D12_RANGE static_ib_read_range;
|
||||||
|
static_ib_read_range.Begin = 0;
|
||||||
|
static_ib_read_range.End = 0;
|
||||||
|
void* static_ib_mapping;
|
||||||
|
if (FAILED(static_ib_upload_->Map(0, &static_ib_read_range,
|
||||||
|
&static_ib_mapping))) {
|
||||||
|
XELOGE(
|
||||||
|
"Failed to map the upload buffer for the primitive conversion "
|
||||||
|
"static index buffer");
|
||||||
|
Shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint16_t* static_ib_data = reinterpret_cast<uint16_t*>(static_ib_mapping);
|
||||||
|
// Triangle fans as triangle lists.
|
||||||
|
// https://docs.microsoft.com/en-us/windows/desktop/direct3d9/triangle-fans
|
||||||
|
// Ordered as (v1, v2, v0), (v2, v3, v0).
|
||||||
|
uint16_t* static_ib_data_triangle_fan =
|
||||||
|
&static_ib_data[kStaticIBTriangleFanOffset];
|
||||||
|
for (uint32_t i = 2; i < kMaxNonIndexedVertices; ++i) {
|
||||||
|
*(static_ib_data_triangle_fan++) = i;
|
||||||
|
*(static_ib_data_triangle_fan++) = i - 1;
|
||||||
|
*(static_ib_data_triangle_fan++) = 0;
|
||||||
|
}
|
||||||
|
static_ib_upload_->Unmap(0, nullptr);
|
||||||
|
// Not uploaded yet.
|
||||||
|
static_ib_upload_frame_ = UINT64_MAX;
|
||||||
|
if (FAILED(device->CreateCommittedResource(
|
||||||
|
&ui::d3d12::util::kHeapPropertiesDefault, D3D12_HEAP_FLAG_NONE,
|
||||||
|
&static_ib_desc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr,
|
||||||
|
IID_PPV_ARGS(&static_ib_)))) {
|
||||||
|
XELOGE("Failed to create the primitive conversion static index buffer");
|
||||||
|
Shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
static_ib_gpu_address_ = static_ib_->GetGPUVirtualAddress();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrimitiveConverter::Shutdown() { buffer_pool_.reset(); }
|
void PrimitiveConverter::Shutdown() {
|
||||||
|
ui::d3d12::util::ReleaseAndNull(static_ib_);
|
||||||
|
ui::d3d12::util::ReleaseAndNull(static_ib_upload_);
|
||||||
|
buffer_pool_.reset();
|
||||||
|
}
|
||||||
|
|
||||||
void PrimitiveConverter::ClearCache() { buffer_pool_->ClearCache(); }
|
void PrimitiveConverter::ClearCache() { buffer_pool_->ClearCache(); }
|
||||||
|
|
||||||
void PrimitiveConverter::BeginFrame(ID3D12GraphicsCommandList* command_list) {
|
void PrimitiveConverter::BeginFrame() {
|
||||||
buffer_pool_->BeginFrame();
|
buffer_pool_->BeginFrame();
|
||||||
// TODO(Triang3l): Create the static index buffer for unindexed triangle fans.
|
|
||||||
|
// Got a command list now - upload and transition the static index buffer if
|
||||||
|
// needed.
|
||||||
|
if (static_ib_upload_ != nullptr) {
|
||||||
|
auto context = command_processor_->GetD3D12Context();
|
||||||
|
if (static_ib_upload_frame_ == UINT64_MAX) {
|
||||||
|
// Not uploaded yet - upload.
|
||||||
|
command_processor_->GetCurrentCommandList()->CopyResource(
|
||||||
|
static_ib_, static_ib_upload_);
|
||||||
|
command_processor_->PushTransitionBarrier(
|
||||||
|
static_ib_, D3D12_RESOURCE_STATE_COPY_DEST,
|
||||||
|
D3D12_RESOURCE_STATE_INDEX_BUFFER);
|
||||||
|
static_ib_upload_frame_ = context->GetCurrentFrame();
|
||||||
|
} else if (context->GetLastCompletedFrame() >= static_ib_upload_frame_) {
|
||||||
|
// Completely uploaded - release the upload buffer.
|
||||||
|
static_ib_upload_->Release();
|
||||||
|
static_ib_upload_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrimitiveConverter::EndFrame() { buffer_pool_->EndFrame(); }
|
void PrimitiveConverter::EndFrame() { buffer_pool_->EndFrame(); }
|
||||||
|
@ -194,6 +277,21 @@ void* PrimitiveConverter::AllocateIndices(
|
||||||
return mapping + simd_offset;
|
return mapping + simd_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
D3D12_GPU_VIRTUAL_ADDRESS PrimitiveConverter::GetStaticIndexBuffer(
|
||||||
|
PrimitiveType source_type, uint32_t index_count,
|
||||||
|
uint32_t& index_count_out) const {
|
||||||
|
if (index_count >= kMaxNonIndexedVertices) {
|
||||||
|
assert_always();
|
||||||
|
return D3D12_GPU_VIRTUAL_ADDRESS(0);
|
||||||
|
}
|
||||||
|
if (source_type == PrimitiveType::kTriangleFan) {
|
||||||
|
index_count_out = (std::max(index_count, uint32_t(2)) - 2) * 3;
|
||||||
|
return static_ib_gpu_address_ +
|
||||||
|
kStaticIBTriangleFanOffset * sizeof(uint16_t);
|
||||||
|
}
|
||||||
|
return D3D12_GPU_VIRTUAL_ADDRESS(0);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace d3d12
|
} // namespace d3d12
|
||||||
} // namespace gpu
|
} // namespace gpu
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
|
@ -24,6 +24,8 @@ namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
namespace d3d12 {
|
namespace d3d12 {
|
||||||
|
|
||||||
|
class D3D12CommandProcessor;
|
||||||
|
|
||||||
// Index buffer cache for primitive types not natively supported by Direct3D 12:
|
// Index buffer cache for primitive types not natively supported by Direct3D 12:
|
||||||
// - Triangle and line strips with non-0xFFFF/0xFFFFFFFF reset index.
|
// - Triangle and line strips with non-0xFFFF/0xFFFFFFFF reset index.
|
||||||
// - Triangle fans.
|
// - Triangle fans.
|
||||||
|
@ -32,16 +34,16 @@ namespace d3d12 {
|
||||||
// vertex count value).
|
// vertex count value).
|
||||||
class PrimitiveConverter {
|
class PrimitiveConverter {
|
||||||
public:
|
public:
|
||||||
PrimitiveConverter(ui::d3d12::D3D12Context* context,
|
PrimitiveConverter(D3D12CommandProcessor* command_processor,
|
||||||
RegisterFile* register_file, Memory* memory,
|
RegisterFile* register_file, Memory* memory,
|
||||||
SharedMemory* shared_memory);
|
SharedMemory* shared_memory);
|
||||||
~PrimitiveConverter();
|
~PrimitiveConverter();
|
||||||
|
|
||||||
void Initialize();
|
bool Initialize();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void ClearCache();
|
void ClearCache();
|
||||||
|
|
||||||
void BeginFrame(ID3D12GraphicsCommandList* command_list);
|
void BeginFrame();
|
||||||
void EndFrame();
|
void EndFrame();
|
||||||
|
|
||||||
// Returns the primitive type that the original type will be converted to.
|
// Returns the primitive type that the original type will be converted to.
|
||||||
|
@ -70,6 +72,12 @@ class PrimitiveConverter {
|
||||||
D3D12_GPU_VIRTUAL_ADDRESS& gpu_address_out,
|
D3D12_GPU_VIRTUAL_ADDRESS& gpu_address_out,
|
||||||
uint32_t& index_count_out);
|
uint32_t& index_count_out);
|
||||||
|
|
||||||
|
// Returns the 16-bit index buffer for drawing unsupported non-indexed
|
||||||
|
// primitives in INDEX_BUFFER state, for non-indexed drawing. Returns 0 if
|
||||||
|
// conversion is not available (can draw natively).
|
||||||
|
D3D12_GPU_VIRTUAL_ADDRESS GetStaticIndexBuffer(
|
||||||
|
PrimitiveType source_type, uint32_t index_count,
|
||||||
|
uint32_t& index_count_out) const;
|
||||||
// TODO(Triang3l): A function that returns a static index buffer for
|
// TODO(Triang3l): A function that returns a static index buffer for
|
||||||
// non-indexed drawing of unsupported primitives
|
// non-indexed drawing of unsupported primitives
|
||||||
|
|
||||||
|
@ -81,13 +89,30 @@ class PrimitiveConverter {
|
||||||
uint32_t simd_offset,
|
uint32_t simd_offset,
|
||||||
D3D12_GPU_VIRTUAL_ADDRESS& gpu_address_out);
|
D3D12_GPU_VIRTUAL_ADDRESS& gpu_address_out);
|
||||||
|
|
||||||
ui::d3d12::D3D12Context* context_;
|
D3D12CommandProcessor* command_processor_;
|
||||||
RegisterFile* register_file_;
|
RegisterFile* register_file_;
|
||||||
Memory* memory_;
|
Memory* memory_;
|
||||||
SharedMemory* shared_memory_;
|
SharedMemory* shared_memory_;
|
||||||
|
|
||||||
std::unique_ptr<ui::d3d12::UploadBufferPool> buffer_pool_ = nullptr;
|
std::unique_ptr<ui::d3d12::UploadBufferPool> buffer_pool_ = nullptr;
|
||||||
|
|
||||||
|
// Static index buffers for emulating unsupported primitive types when drawing
|
||||||
|
// without an index buffer.
|
||||||
|
// CPU-side, used only for uploading - destroyed once the copy commands have
|
||||||
|
// been completed.
|
||||||
|
ID3D12Resource* static_ib_upload_ = nullptr;
|
||||||
|
uint64_t static_ib_upload_frame_;
|
||||||
|
// GPU-side - used for drawing.
|
||||||
|
ID3D12Resource* static_ib_ = nullptr;
|
||||||
|
D3D12_GPU_VIRTUAL_ADDRESS static_ib_gpu_address_;
|
||||||
|
// In PM4 draw packets, 16 bits are used for the vertex count.
|
||||||
|
static constexpr uint32_t kMaxNonIndexedVertices = 65535;
|
||||||
|
static constexpr uint32_t kStaticIBTriangleFanOffset = 0;
|
||||||
|
static constexpr uint32_t kStaticIBTriangleFanCount =
|
||||||
|
(kMaxNonIndexedVertices - 2) * 3;
|
||||||
|
static constexpr uint32_t kStaticIBTotalCount =
|
||||||
|
kStaticIBTriangleFanOffset + kStaticIBTriangleFanCount;
|
||||||
|
|
||||||
struct ConvertedIndices {
|
struct ConvertedIndices {
|
||||||
D3D12_GPU_VIRTUAL_ADDRESS gpu_address;
|
D3D12_GPU_VIRTUAL_ADDRESS gpu_address;
|
||||||
PrimitiveType primitive_type;
|
PrimitiveType primitive_type;
|
||||||
|
|
|
@ -76,23 +76,13 @@ bool RenderTargetCache::Initialize() {
|
||||||
|
|
||||||
// Create the buffer for reinterpreting EDRAM contents.
|
// Create the buffer for reinterpreting EDRAM contents.
|
||||||
D3D12_RESOURCE_DESC edram_buffer_desc;
|
D3D12_RESOURCE_DESC edram_buffer_desc;
|
||||||
edram_buffer_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
ui::d3d12::util::FillBufferResourceDesc(
|
||||||
edram_buffer_desc.Alignment = 0;
|
edram_buffer_desc, kEDRAMBufferSize,
|
||||||
edram_buffer_desc.Width = kEDRAMBufferSize;
|
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
|
||||||
edram_buffer_desc.Height = 1;
|
|
||||||
edram_buffer_desc.DepthOrArraySize = 1;
|
|
||||||
edram_buffer_desc.MipLevels = 1;
|
|
||||||
edram_buffer_desc.Format = DXGI_FORMAT_UNKNOWN;
|
|
||||||
edram_buffer_desc.SampleDesc.Count = 1;
|
|
||||||
edram_buffer_desc.SampleDesc.Quality = 0;
|
|
||||||
edram_buffer_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
|
||||||
edram_buffer_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
|
||||||
D3D12_HEAP_PROPERTIES edram_buffer_heap_properties = {};
|
|
||||||
edram_buffer_heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
|
||||||
// The first operation will be a clear.
|
// The first operation will be a clear.
|
||||||
edram_buffer_state_ = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
|
edram_buffer_state_ = D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
|
||||||
if (FAILED(device->CreateCommittedResource(
|
if (FAILED(device->CreateCommittedResource(
|
||||||
&edram_buffer_heap_properties, D3D12_HEAP_FLAG_NONE,
|
&ui::d3d12::util::kHeapPropertiesDefault, D3D12_HEAP_FLAG_NONE,
|
||||||
&edram_buffer_desc, edram_buffer_state_, nullptr,
|
&edram_buffer_desc, edram_buffer_state_, nullptr,
|
||||||
IID_PPV_ARGS(&edram_buffer_)))) {
|
IID_PPV_ARGS(&edram_buffer_)))) {
|
||||||
XELOGE("Failed to create the EDRAM buffer");
|
XELOGE("Failed to create the EDRAM buffer");
|
||||||
|
|
|
@ -42,19 +42,10 @@ bool SharedMemory::Initialize() {
|
||||||
auto context = command_processor_->GetD3D12Context();
|
auto context = command_processor_->GetD3D12Context();
|
||||||
auto device = context->GetD3D12Provider()->GetDevice();
|
auto device = context->GetD3D12Provider()->GetDevice();
|
||||||
|
|
||||||
buffer_state_ = D3D12_RESOURCE_STATE_COPY_DEST;
|
|
||||||
D3D12_RESOURCE_DESC buffer_desc;
|
D3D12_RESOURCE_DESC buffer_desc;
|
||||||
buffer_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
ui::d3d12::util::FillBufferResourceDesc(
|
||||||
buffer_desc.Alignment = 0;
|
buffer_desc, kBufferSize, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
|
||||||
buffer_desc.Width = kBufferSize;
|
buffer_state_ = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||||
buffer_desc.Height = 1;
|
|
||||||
buffer_desc.DepthOrArraySize = 1;
|
|
||||||
buffer_desc.MipLevels = 1;
|
|
||||||
buffer_desc.Format = DXGI_FORMAT_UNKNOWN;
|
|
||||||
buffer_desc.SampleDesc.Count = 1;
|
|
||||||
buffer_desc.SampleDesc.Quality = 0;
|
|
||||||
buffer_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
|
||||||
buffer_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
|
||||||
if (FLAGS_d3d12_tiled_resources) {
|
if (FLAGS_d3d12_tiled_resources) {
|
||||||
if (FAILED(device->CreateReservedResource(
|
if (FAILED(device->CreateReservedResource(
|
||||||
&buffer_desc, buffer_state_, nullptr, IID_PPV_ARGS(&buffer_)))) {
|
&buffer_desc, buffer_state_, nullptr, IID_PPV_ARGS(&buffer_)))) {
|
||||||
|
@ -63,11 +54,9 @@ bool SharedMemory::Initialize() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
D3D12_HEAP_PROPERTIES heap_properties = {};
|
|
||||||
heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
|
||||||
if (FAILED(device->CreateCommittedResource(
|
if (FAILED(device->CreateCommittedResource(
|
||||||
&heap_properties, D3D12_HEAP_FLAG_NONE, &buffer_desc, buffer_state_,
|
&ui::d3d12::util::kHeapPropertiesDefault, D3D12_HEAP_FLAG_NONE,
|
||||||
nullptr, IID_PPV_ARGS(&buffer_)))) {
|
&buffer_desc, buffer_state_, nullptr, IID_PPV_ARGS(&buffer_)))) {
|
||||||
XELOGE("Shared memory: Failed to create the 512 MB buffer");
|
XELOGE("Shared memory: Failed to create the 512 MB buffer");
|
||||||
Shutdown();
|
Shutdown();
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -819,14 +819,12 @@ TextureCache::Texture* TextureCache::FindOrCreateTexture(TextureKey key) {
|
||||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||||
auto device =
|
auto device =
|
||||||
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice();
|
command_processor_->GetD3D12Context()->GetD3D12Provider()->GetDevice();
|
||||||
D3D12_HEAP_PROPERTIES heap_properties = {};
|
|
||||||
heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
|
||||||
// Assuming untiling will be the next operation.
|
// Assuming untiling will be the next operation.
|
||||||
D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_COPY_DEST;
|
D3D12_RESOURCE_STATES state = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||||
ID3D12Resource* resource;
|
ID3D12Resource* resource;
|
||||||
if (FAILED(device->CreateCommittedResource(
|
if (FAILED(device->CreateCommittedResource(
|
||||||
&heap_properties, D3D12_HEAP_FLAG_NONE, &desc, state, nullptr,
|
&ui::d3d12::util::kHeapPropertiesDefault, D3D12_HEAP_FLAG_NONE, &desc,
|
||||||
IID_PPV_ARGS(&resource)))) {
|
state, nullptr, IID_PPV_ARGS(&resource)))) {
|
||||||
LogTextureKeyAction(key, "Failed to create");
|
LogTextureKeyAction(key, "Failed to create");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,8 +62,6 @@ bool D3D12ImmediateTexture::Initialize(ID3D12Device* device) {
|
||||||
// The first operation will likely be copying the contents.
|
// The first operation will likely be copying the contents.
|
||||||
state_ = D3D12_RESOURCE_STATE_COPY_DEST;
|
state_ = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||||
|
|
||||||
D3D12_HEAP_PROPERTIES heap_properties = {};
|
|
||||||
heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
|
||||||
D3D12_RESOURCE_DESC resource_desc;
|
D3D12_RESOURCE_DESC resource_desc;
|
||||||
resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||||
resource_desc.Alignment = 0;
|
resource_desc.Alignment = 0;
|
||||||
|
@ -77,8 +75,8 @@ bool D3D12ImmediateTexture::Initialize(ID3D12Device* device) {
|
||||||
resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||||
resource_desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
resource_desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||||
if (FAILED(device->CreateCommittedResource(
|
if (FAILED(device->CreateCommittedResource(
|
||||||
&heap_properties, D3D12_HEAP_FLAG_NONE, &resource_desc, state_,
|
&util::kHeapPropertiesDefault, D3D12_HEAP_FLAG_NONE, &resource_desc,
|
||||||
nullptr, IID_PPV_ARGS(&resource_)))) {
|
state_, nullptr, IID_PPV_ARGS(&resource_)))) {
|
||||||
XELOGE("Failed to create a %ux%u texture for immediate drawing", width,
|
XELOGE("Failed to create a %ux%u texture for immediate drawing", width,
|
||||||
height);
|
height);
|
||||||
return false;
|
return false;
|
||||||
|
@ -173,8 +171,7 @@ bool D3D12ImmediateDrawer::Initialize() {
|
||||||
root_signature_desc.pStaticSamplers = nullptr;
|
root_signature_desc.pStaticSamplers = nullptr;
|
||||||
root_signature_desc.Flags =
|
root_signature_desc.Flags =
|
||||||
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
|
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
|
||||||
root_signature_ =
|
root_signature_ = util::CreateRootSignature(device, root_signature_desc);
|
||||||
ui::d3d12::util::CreateRootSignature(device, root_signature_desc);
|
|
||||||
if (root_signature_ == nullptr) {
|
if (root_signature_ == nullptr) {
|
||||||
XELOGE("Failed to create the immediate drawer root signature");
|
XELOGE("Failed to create the immediate drawer root signature");
|
||||||
Shutdown();
|
Shutdown();
|
||||||
|
@ -362,23 +359,12 @@ void D3D12ImmediateDrawer::UpdateTexture(ImmediateTexture* texture,
|
||||||
UINT64 upload_size;
|
UINT64 upload_size;
|
||||||
device->GetCopyableFootprints(&texture_desc, 0, 1, 0, &upload_footprint,
|
device->GetCopyableFootprints(&texture_desc, 0, 1, 0, &upload_footprint,
|
||||||
nullptr, nullptr, &upload_size);
|
nullptr, nullptr, &upload_size);
|
||||||
D3D12_HEAP_PROPERTIES heap_properties = {};
|
|
||||||
heap_properties.Type = D3D12_HEAP_TYPE_UPLOAD;
|
|
||||||
D3D12_RESOURCE_DESC buffer_desc;
|
D3D12_RESOURCE_DESC buffer_desc;
|
||||||
buffer_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
util::FillBufferResourceDesc(buffer_desc, upload_size,
|
||||||
buffer_desc.Alignment = 0;
|
D3D12_RESOURCE_FLAG_NONE);
|
||||||
buffer_desc.Width = upload_size;
|
|
||||||
buffer_desc.Height = 1;
|
|
||||||
buffer_desc.DepthOrArraySize = 1;
|
|
||||||
buffer_desc.MipLevels = 1;
|
|
||||||
buffer_desc.Format = DXGI_FORMAT_UNKNOWN;
|
|
||||||
buffer_desc.SampleDesc.Count = 1;
|
|
||||||
buffer_desc.SampleDesc.Quality = 0;
|
|
||||||
buffer_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
|
||||||
buffer_desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
|
||||||
ID3D12Resource* buffer;
|
ID3D12Resource* buffer;
|
||||||
if (FAILED(device->CreateCommittedResource(
|
if (FAILED(device->CreateCommittedResource(
|
||||||
&heap_properties, D3D12_HEAP_FLAG_NONE, &buffer_desc,
|
&util::kHeapPropertiesUpload, D3D12_HEAP_FLAG_NONE, &buffer_desc,
|
||||||
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&buffer)))) {
|
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&buffer)))) {
|
||||||
XELOGE(
|
XELOGE(
|
||||||
"Failed to create an upload buffer for a %ux%u texture for "
|
"Failed to create an upload buffer for a %ux%u texture for "
|
||||||
|
|
|
@ -17,6 +17,9 @@ namespace ui {
|
||||||
namespace d3d12 {
|
namespace d3d12 {
|
||||||
namespace util {
|
namespace util {
|
||||||
|
|
||||||
|
const D3D12_HEAP_PROPERTIES kHeapPropertiesDefault = {D3D12_HEAP_TYPE_DEFAULT};
|
||||||
|
const D3D12_HEAP_PROPERTIES kHeapPropertiesUpload = {D3D12_HEAP_TYPE_UPLOAD};
|
||||||
|
|
||||||
ID3D12RootSignature* CreateRootSignature(
|
ID3D12RootSignature* CreateRootSignature(
|
||||||
ID3D12Device* device, const D3D12_ROOT_SIGNATURE_DESC& desc) {
|
ID3D12Device* device, const D3D12_ROOT_SIGNATURE_DESC& desc) {
|
||||||
ID3DBlob* blob;
|
ID3DBlob* blob;
|
||||||
|
|
|
@ -17,6 +17,9 @@ namespace ui {
|
||||||
namespace d3d12 {
|
namespace d3d12 {
|
||||||
namespace util {
|
namespace util {
|
||||||
|
|
||||||
|
extern const D3D12_HEAP_PROPERTIES kHeapPropertiesDefault;
|
||||||
|
extern const D3D12_HEAP_PROPERTIES kHeapPropertiesUpload;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool ReleaseAndNull(T& object) {
|
inline bool ReleaseAndNull(T& object) {
|
||||||
if (object != nullptr) {
|
if (object != nullptr) {
|
||||||
|
@ -35,6 +38,21 @@ ID3D12PipelineState* CreateComputePipeline(ID3D12Device* device,
|
||||||
size_t shader_size,
|
size_t shader_size,
|
||||||
ID3D12RootSignature* root_signature);
|
ID3D12RootSignature* root_signature);
|
||||||
|
|
||||||
|
inline void FillBufferResourceDesc(D3D12_RESOURCE_DESC& desc, UINT64 size,
|
||||||
|
D3D12_RESOURCE_FLAGS flags) {
|
||||||
|
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||||
|
desc.Alignment = 0;
|
||||||
|
desc.Width = size;
|
||||||
|
desc.Height = 1;
|
||||||
|
desc.DepthOrArraySize = 1;
|
||||||
|
desc.MipLevels = 1;
|
||||||
|
desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.SampleDesc.Quality = 0;
|
||||||
|
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||||
|
desc.Flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
void CreateRawBufferSRV(ID3D12Device* device,
|
void CreateRawBufferSRV(ID3D12Device* device,
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE handle,
|
D3D12_CPU_DESCRIPTOR_HANDLE handle,
|
||||||
ID3D12Resource* buffer, uint32_t size,
|
ID3D12Resource* buffer, uint32_t size,
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "xenia/base/assert.h"
|
#include "xenia/base/assert.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
|
#include "xenia/ui/d3d12/d3d12_util.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
@ -157,23 +158,12 @@ bool UploadBufferPool::BeginNextPage() {
|
||||||
|
|
||||||
if (unsent_ == nullptr) {
|
if (unsent_ == nullptr) {
|
||||||
auto device = context_->GetD3D12Provider()->GetDevice();
|
auto device = context_->GetD3D12Provider()->GetDevice();
|
||||||
D3D12_HEAP_PROPERTIES heap_properties = {};
|
|
||||||
heap_properties.Type = D3D12_HEAP_TYPE_UPLOAD;
|
|
||||||
D3D12_RESOURCE_DESC buffer_desc;
|
D3D12_RESOURCE_DESC buffer_desc;
|
||||||
buffer_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
util::FillBufferResourceDesc(buffer_desc, page_size_,
|
||||||
buffer_desc.Alignment = 0;
|
D3D12_RESOURCE_FLAG_NONE);
|
||||||
buffer_desc.Width = page_size_;
|
|
||||||
buffer_desc.Height = 1;
|
|
||||||
buffer_desc.DepthOrArraySize = 1;
|
|
||||||
buffer_desc.MipLevels = 1;
|
|
||||||
buffer_desc.Format = DXGI_FORMAT_UNKNOWN;
|
|
||||||
buffer_desc.SampleDesc.Count = 1;
|
|
||||||
buffer_desc.SampleDesc.Quality = 0;
|
|
||||||
buffer_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
|
||||||
buffer_desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
|
||||||
ID3D12Resource* buffer_resource;
|
ID3D12Resource* buffer_resource;
|
||||||
if (FAILED(device->CreateCommittedResource(
|
if (FAILED(device->CreateCommittedResource(
|
||||||
&heap_properties, D3D12_HEAP_FLAG_NONE, &buffer_desc,
|
&util::kHeapPropertiesUpload, D3D12_HEAP_FLAG_NONE, &buffer_desc,
|
||||||
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr,
|
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr,
|
||||||
IID_PPV_ARGS(&buffer_resource)))) {
|
IID_PPV_ARGS(&buffer_resource)))) {
|
||||||
XELOGE("Failed to create a D3D upload buffer with %u bytes", page_size_);
|
XELOGE("Failed to create a D3D upload buffer with %u bytes", page_size_);
|
||||||
|
|
Loading…
Reference in New Issue