Merge branch 'master' into vulkan

This commit is contained in:
Triang3l
2020-09-26 22:08:02 +03:00
13 changed files with 219 additions and 281 deletions

View File

@@ -28,27 +28,9 @@ namespace d3d12 {
#include "xenia/ui/shaders/bytecode/d3d12_5_1/immediate_ps.h"
#include "xenia/ui/shaders/bytecode/d3d12_5_1/immediate_vs.h"
class D3D12ImmediateTexture : public ImmediateTexture {
public:
static constexpr DXGI_FORMAT kFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
D3D12ImmediateTexture(uint32_t width, uint32_t height,
ID3D12Resource* resource_if_exists,
ImmediateTextureFilter filter, bool is_repeated);
~D3D12ImmediateTexture() override;
ID3D12Resource* resource() const { return resource_; }
ImmediateTextureFilter filter() const { return filter_; }
bool is_repeated() const { return is_repeated_; }
private:
ID3D12Resource* resource_;
ImmediateTextureFilter filter_;
bool is_repeated_;
};
D3D12ImmediateTexture::D3D12ImmediateTexture(uint32_t width, uint32_t height,
ID3D12Resource* resource_if_exists,
ImmediateTextureFilter filter,
bool is_repeated)
D3D12ImmediateDrawer::D3D12ImmediateTexture::D3D12ImmediateTexture(
uint32_t width, uint32_t height, ID3D12Resource* resource_if_exists,
ImmediateTextureFilter filter, bool is_repeated)
: ImmediateTexture(width, height),
resource_(resource_if_exists),
filter_(filter),
@@ -59,9 +41,12 @@ D3D12ImmediateTexture::D3D12ImmediateTexture(uint32_t width, uint32_t height,
handle = reinterpret_cast<uintptr_t>(this);
}
D3D12ImmediateTexture::~D3D12ImmediateTexture() {
D3D12ImmediateDrawer::D3D12ImmediateTexture::~D3D12ImmediateTexture() {
if (resource_) {
resource_->Release();
// TODO(Triang3l): Track last usage submission because it turns out that
// deletion in the ImGui and the profiler actually happens before after
// awaiting submission completion.
}
}
@@ -77,15 +62,6 @@ bool D3D12ImmediateDrawer::Initialize() {
// Create the root signature.
D3D12_ROOT_PARAMETER root_parameters[size_t(RootParameter::kCount)];
D3D12_DESCRIPTOR_RANGE descriptor_range_texture, descriptor_range_sampler;
{
auto& root_parameter =
root_parameters[size_t(RootParameter::kRestrictTextureSamples)];
root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
root_parameter.Constants.ShaderRegister = 0;
root_parameter.Constants.RegisterSpace = 0;
root_parameter.Constants.Num32BitValues = 1;
root_parameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
}
{
auto& root_parameter = root_parameters[size_t(RootParameter::kTexture)];
root_parameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
@@ -216,20 +192,12 @@ bool D3D12ImmediateDrawer::Initialize() {
sampler_heap_gpu_start_ = sampler_heap_->GetGPUDescriptorHandleForHeapStart();
uint32_t sampler_size = provider.GetSamplerDescriptorSize();
// Nearest neighbor, clamp.
D3D12_SAMPLER_DESC sampler_desc;
D3D12_SAMPLER_DESC sampler_desc = {};
sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
sampler_desc.MipLODBias = 0.0f;
sampler_desc.MaxAnisotropy = 1;
sampler_desc.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
sampler_desc.BorderColor[0] = 0.0f;
sampler_desc.BorderColor[1] = 0.0f;
sampler_desc.BorderColor[2] = 0.0f;
sampler_desc.BorderColor[3] = 0.0f;
sampler_desc.MinLOD = 0.0f;
sampler_desc.MaxLOD = 0.0f;
D3D12_CPU_DESCRIPTOR_HANDLE sampler_handle;
sampler_handle.ptr = sampler_heap_cpu_start_.ptr +
uint32_t(SamplerIndex::kNearestClamp) * sampler_size;
@@ -239,19 +207,18 @@ bool D3D12ImmediateDrawer::Initialize() {
sampler_handle.ptr = sampler_heap_cpu_start_.ptr +
uint32_t(SamplerIndex::kLinearClamp) * sampler_size;
device->CreateSampler(&sampler_desc, sampler_handle);
// Nearest neighbor, repeat.
sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
// Bilinear, repeat.
sampler_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
sampler_handle.ptr = sampler_heap_cpu_start_.ptr +
uint32_t(SamplerIndex::kNearestRepeat) * sampler_size;
device->CreateSampler(&sampler_desc, sampler_handle);
// Bilinear, repeat.
sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
sampler_handle.ptr = sampler_heap_cpu_start_.ptr +
uint32_t(SamplerIndex::kLinearRepeat) * sampler_size;
device->CreateSampler(&sampler_desc, sampler_handle);
// Nearest neighbor, repeat.
sampler_desc.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
sampler_handle.ptr = sampler_heap_cpu_start_.ptr +
uint32_t(SamplerIndex::kNearestRepeat) * sampler_size;
device->CreateSampler(&sampler_desc, sampler_handle);
// Create pools for draws.
vertex_buffer_pool_ = std::make_unique<D3D12UploadBufferPool>(provider);
@@ -333,25 +300,30 @@ std::unique_ptr<ImmediateTexture> D3D12ImmediateDrawer::CreateTexture(
void* upload_buffer_mapping;
if (SUCCEEDED(upload_buffer->Map(0, &upload_buffer_read_range,
&upload_buffer_mapping))) {
uint8_t* upload_buffer_row =
reinterpret_cast<uint8_t*>(upload_buffer_mapping) +
upload_footprint.Offset;
const uint8_t* data_row = data;
for (uint32_t i = 0; i < height; ++i) {
std::memcpy(upload_buffer_row, data_row, width * 4);
data_row += width * 4;
upload_buffer_row += upload_footprint.Footprint.RowPitch;
size_t data_row_length = sizeof(uint32_t) * width;
if (data_row_length == upload_footprint.Footprint.RowPitch) {
std::memcpy(upload_buffer_mapping, data, data_row_length * height);
} else {
uint8_t* upload_buffer_row =
reinterpret_cast<uint8_t*>(upload_buffer_mapping) +
upload_footprint.Offset;
const uint8_t* data_row = data;
for (uint32_t i = 0; i < height; ++i) {
std::memcpy(upload_buffer_row, data_row, data_row_length);
data_row += data_row_length;
upload_buffer_row += upload_footprint.Footprint.RowPitch;
}
}
upload_buffer->Unmap(0, nullptr);
// Defer uploading and transition to the next draw.
PendingTextureUpload pending_upload;
PendingTextureUpload& pending_upload =
texture_uploads_pending_.emplace_back();
// While the upload has not been yet completed, keep a reference to the
// resource because its lifetime is not tied to that of the
// ImmediateTexture (and thus to context's submissions) now.
resource->AddRef();
pending_upload.texture = resource;
pending_upload.buffer = upload_buffer;
texture_uploads_pending_.push_back(pending_upload);
} else {
XELOGE(
"Failed to map a Direct3D 12 upload buffer for a {}x{} texture for "
@@ -401,9 +373,7 @@ void D3D12ImmediateDrawer::Begin(int render_target_width,
// Release upload buffers for completed texture uploads.
auto erase_uploads_end = texture_uploads_submitted_.begin();
while (erase_uploads_end != texture_uploads_submitted_.end()) {
uint64_t upload_fence_value = erase_uploads_end->fence_value;
if (upload_fence_value > completed_fence_value) {
++erase_uploads_end;
if (erase_uploads_end->fence_value > completed_fence_value) {
break;
}
erase_uploads_end->buffer->Release();
@@ -606,12 +576,6 @@ void D3D12ImmediateDrawer::Draw(const ImmediateDraw& draw) {
uint32_t(sampler_index)));
}
// Set whether texture coordinates need to be restricted.
uint32_t restrict_texture_samples = draw.restrict_texture_samples ? 1 : 0;
current_command_list_->SetGraphicsRoot32BitConstants(
UINT(RootParameter::kRestrictTextureSamples), 1,
&restrict_texture_samples, 0);
// Set the primitive type and the pipeline state for it.
D3D_PRIMITIVE_TOPOLOGY primitive_topology;
ID3D12PipelineState* pipeline_state;
@@ -668,9 +632,7 @@ void D3D12ImmediateDrawer::UploadTextures() {
// pipeline barriers).
std::vector<D3D12_RESOURCE_BARRIER> barriers;
barriers.reserve(texture_uploads_pending_.size());
while (!texture_uploads_pending_.empty()) {
const PendingTextureUpload& pending_upload =
texture_uploads_pending_.back();
for (const PendingTextureUpload& pending_upload : texture_uploads_pending_) {
ID3D12Resource* texture = pending_upload.texture;
D3D12_RESOURCE_DESC texture_desc = texture->GetDesc();
@@ -694,15 +656,15 @@ void D3D12ImmediateDrawer::UploadTextures() {
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
SubmittedTextureUpload submitted_upload;
SubmittedTextureUpload& submitted_upload =
texture_uploads_submitted_.emplace_back();
// Transfer the reference to the texture - need to keep it until the upload
// is completed.
submitted_upload.texture = texture;
submitted_upload.buffer = pending_upload.buffer;
submitted_upload.fence_value = current_fence_value;
texture_uploads_submitted_.push_back(submitted_upload);
texture_uploads_pending_.pop_back();
}
texture_uploads_pending_.clear();
assert_false(barriers.empty());
current_command_list_->ResourceBarrier(UINT(barriers.size()),
barriers.data());

View File

@@ -36,7 +36,7 @@ class D3D12ImmediateDrawer : public ImmediateDrawer {
std::unique_ptr<ImmediateTexture> CreateTexture(uint32_t width,
uint32_t height,
ImmediateTextureFilter filter,
bool repeat,
bool is_repeated,
const uint8_t* data) override;
void Begin(int render_target_width, int render_target_height) override;
@@ -46,13 +46,29 @@ class D3D12ImmediateDrawer : public ImmediateDrawer {
void End() override;
private:
class D3D12ImmediateTexture : public ImmediateTexture {
public:
static constexpr DXGI_FORMAT kFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
D3D12ImmediateTexture(uint32_t width, uint32_t height,
ID3D12Resource* resource_if_exists,
ImmediateTextureFilter filter, bool is_repeated);
~D3D12ImmediateTexture() override;
ID3D12Resource* resource() const { return resource_; }
ImmediateTextureFilter filter() const { return filter_; }
bool is_repeated() const { return is_repeated_; }
private:
ID3D12Resource* resource_;
ImmediateTextureFilter filter_;
bool is_repeated_;
};
void UploadTextures();
D3D12Context& context_;
ID3D12RootSignature* root_signature_ = nullptr;
enum class RootParameter {
kRestrictTextureSamples,
kTexture,
kSampler,
kViewportSizeInv,