Merge branch 'master' into vulkan
This commit is contained in:
@@ -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());
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user