[D3D12] Non-indexed triangle fans and resource creation refactoring

This commit is contained in:
Triang3l 2018-09-15 23:41:16 +03:00
parent d1f185c744
commit 5be78ab369
10 changed files with 206 additions and 107 deletions

View File

@ -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;
} }

View File

@ -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

View File

@ -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;

View File

@ -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");

View File

@ -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;

View File

@ -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;
} }

View File

@ -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 "

View File

@ -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;

View File

@ -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,

View File

@ -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_);