atomic cas use prefetchw if available
remove useless memorybarrier remove double membarrier in wait pm4 cmd add int64 cvar use int64 cvar for x64 feature mask Rework some functions that were frontend bound according to vtune placing some of their code in different noinline functions, profiling after indicating l1 cache misses decreased and perf of func increased remove long vpinsrd dep chain code for conversion.h, instead do normal load+bswap or movbe if avail Much faster entry table via split_map, code size could be improved though GetResolveInfo was very large and had impact on icache, mark callees as noinline + msvc pragma optimize small use log2 shifts instead of integer divides in memory minor optimizations in PhysicalHeap::EnableAccessCallbacks, the majority of time in the function is spent looping, NOT calling Protect! Someone should optimize this function and rework the algo completely remove wonky scheduling log message, it was spammy and unhelpful lock count was unnecessary for criticalsection mutex, criticalsection is already a recursive mutex brief notes i gotta run
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -45,7 +45,10 @@
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d12 {
|
||||
|
||||
struct MemExportRange {
|
||||
uint32_t base_address_dwords;
|
||||
uint32_t size_dwords;
|
||||
};
|
||||
class D3D12CommandProcessor final : public CommandProcessor {
|
||||
public:
|
||||
#include "../pm4_command_processor_declare.h"
|
||||
@@ -287,8 +290,21 @@ class D3D12CommandProcessor final : public CommandProcessor {
|
||||
bool IssueDraw(xenos::PrimitiveType primitive_type, uint32_t index_count,
|
||||
IndexBufferInfo* index_buffer_info,
|
||||
bool major_mode_explicit) override;
|
||||
XE_COLD
|
||||
XE_NOINLINE
|
||||
bool HandleMemexportGuestDMA(ID3D12Resource*& scratch_index_buffer,
|
||||
D3D12_INDEX_BUFFER_VIEW& index_buffer_view,
|
||||
uint32_t guest_index_base,
|
||||
bool& retflag);
|
||||
XE_NOINLINE
|
||||
XE_COLD
|
||||
bool GatherMemexportRangesAndMakeResident(bool& retflag);
|
||||
XE_NOINLINE
|
||||
XE_COLD
|
||||
void HandleMemexportDrawOrdering_AndReadback();
|
||||
bool IssueCopy() override;
|
||||
|
||||
XE_NOINLINE
|
||||
bool IssueCopy_ReadbackResolvePath();
|
||||
void InitializeTrace() override;
|
||||
|
||||
private:
|
||||
@@ -363,6 +379,8 @@ class D3D12CommandProcessor final : public CommandProcessor {
|
||||
};
|
||||
// Gets the indices of optional root parameters. Returns the total parameter
|
||||
// count.
|
||||
XE_NOINLINE
|
||||
XE_COLD
|
||||
static uint32_t GetRootBindfulExtraParameterIndices(
|
||||
const DxbcShader* vertex_shader, const DxbcShader* pixel_shader,
|
||||
RootBindfulExtraParameterIndices& indices_out);
|
||||
@@ -437,6 +455,18 @@ class D3D12CommandProcessor final : public CommandProcessor {
|
||||
bool UpdateBindings(const D3D12Shader* vertex_shader,
|
||||
const D3D12Shader* pixel_shader,
|
||||
ID3D12RootSignature* root_signature);
|
||||
XE_COLD
|
||||
XE_NOINLINE
|
||||
void UpdateBindings_UpdateRootBindful();
|
||||
XE_NOINLINE
|
||||
XE_COLD
|
||||
bool UpdateBindings_BindfulPath(
|
||||
const size_t texture_layout_uid_vertex,
|
||||
const std::vector<xe::gpu::DxbcShader::TextureBinding>& textures_vertex,
|
||||
const size_t texture_layout_uid_pixel,
|
||||
const std::vector<xe::gpu::DxbcShader::TextureBinding>* textures_pixel,
|
||||
const size_t sampler_count_vertex, const size_t sampler_count_pixel,
|
||||
bool& retflag);
|
||||
|
||||
// Returns dword count for one element for a memexport format, or 0 if it's
|
||||
// not supported by the D3D12 command processor (if it's smaller that 1 dword,
|
||||
@@ -743,6 +773,9 @@ class D3D12CommandProcessor final : public CommandProcessor {
|
||||
|
||||
draw_util::GetViewportInfoArgs previous_viewport_info_args_;
|
||||
draw_util::ViewportInfo previous_viewport_info_;
|
||||
// scratch memexport data
|
||||
MemExportRange memexport_ranges_[512];
|
||||
uint32_t memexport_range_count_ = 0;
|
||||
};
|
||||
|
||||
} // namespace d3d12
|
||||
|
||||
@@ -266,22 +266,9 @@ void DeferredCommandList::Execute(ID3D12GraphicsCommandList* command_list,
|
||||
|
||||
void* DeferredCommandList::WriteCommand(Command command,
|
||||
size_t arguments_size_bytes) {
|
||||
|
||||
size_t arguments_size_elements =
|
||||
round_up(arguments_size_bytes, sizeof(uintmax_t), false);
|
||||
|
||||
//(arguments_size_bytes + sizeof(uintmax_t) - 1) / sizeof(uintmax_t);
|
||||
#if 0
|
||||
size_t offset = command_stream_.size();
|
||||
command_stream_.resize(offset + kCommandHeaderSizeElements +
|
||||
arguments_size_elements);
|
||||
CommandHeader& header =
|
||||
*reinterpret_cast<CommandHeader*>(command_stream_.data() + offset);
|
||||
header.command = command;
|
||||
header.arguments_size_elements = uint32_t(arguments_size_elements);
|
||||
return command_stream_.data() + (offset + kCommandHeaderSizeElements);
|
||||
#else
|
||||
|
||||
size_t offset = command_stream_.size();
|
||||
constexpr size_t kCommandHeaderSizeBytes =
|
||||
kCommandHeaderSizeElements * sizeof(uintmax_t);
|
||||
@@ -290,9 +277,9 @@ void* DeferredCommandList::WriteCommand(Command command,
|
||||
CommandHeader& header =
|
||||
*reinterpret_cast<CommandHeader*>(command_stream_.data() + offset);
|
||||
header.command = command;
|
||||
header.arguments_size_elements = uint32_t(arguments_size_elements) / sizeof(uintmax_t);
|
||||
header.arguments_size_elements =
|
||||
uint32_t(arguments_size_elements) / sizeof(uintmax_t);
|
||||
return command_stream_.data() + (offset + kCommandHeaderSizeBytes);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace d3d12
|
||||
|
||||
@@ -183,7 +183,7 @@ void PipelineCache::Shutdown() {
|
||||
// creating them.
|
||||
if (!creation_threads_.empty()) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(creation_request_lock_);
|
||||
std::lock_guard<xe_mutex> lock(creation_request_lock_);
|
||||
creation_threads_shutdown_from_ = 0;
|
||||
}
|
||||
creation_request_cond_.notify_all();
|
||||
@@ -681,7 +681,7 @@ void PipelineCache::InitializeShaderStorage(
|
||||
if (!creation_threads_.empty()) {
|
||||
// Submit the pipeline for creation to any available thread.
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(creation_request_lock_);
|
||||
std::lock_guard<xe_mutex> lock(creation_request_lock_);
|
||||
creation_queue_.push_back(new_pipeline);
|
||||
}
|
||||
creation_request_cond_.notify_one();
|
||||
@@ -695,7 +695,7 @@ void PipelineCache::InitializeShaderStorage(
|
||||
CreateQueuedPipelinesOnProcessorThread();
|
||||
if (creation_threads_.size() > creation_thread_original_count) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(creation_request_lock_);
|
||||
std::lock_guard<xe_mutex> lock(creation_request_lock_);
|
||||
creation_threads_shutdown_from_ = creation_thread_original_count;
|
||||
// Assuming the queue is empty because of
|
||||
// CreateQueuedPipelinesOnProcessorThread.
|
||||
@@ -708,7 +708,7 @@ void PipelineCache::InitializeShaderStorage(
|
||||
bool await_creation_completion_event;
|
||||
{
|
||||
// Cleanup so additional threads can be created later again.
|
||||
std::lock_guard<std::mutex> lock(creation_request_lock_);
|
||||
std::lock_guard<xe_mutex> lock(creation_request_lock_);
|
||||
creation_threads_shutdown_from_ = SIZE_MAX;
|
||||
// If the invocation is blocking, all the shader storage
|
||||
// initialization is expected to be done before proceeding, to avoid
|
||||
@@ -813,7 +813,7 @@ void PipelineCache::EndSubmission() {
|
||||
// Await creation of all queued pipelines.
|
||||
bool await_creation_completion_event;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(creation_request_lock_);
|
||||
std::lock_guard<xe_mutex> lock(creation_request_lock_);
|
||||
// Assuming the creation queue is already empty (because the processor
|
||||
// thread also worked on creating the leftover pipelines), so only check
|
||||
// if there are threads with pipelines currently being created.
|
||||
@@ -834,7 +834,7 @@ bool PipelineCache::IsCreatingPipelines() {
|
||||
if (creation_threads_.empty()) {
|
||||
return false;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(creation_request_lock_);
|
||||
std::lock_guard<xe_mutex> lock(creation_request_lock_);
|
||||
return !creation_queue_.empty() || creation_threads_busy_ != 0;
|
||||
}
|
||||
|
||||
@@ -1076,7 +1076,7 @@ bool PipelineCache::ConfigurePipeline(
|
||||
if (!creation_threads_.empty()) {
|
||||
// Submit the pipeline for creation to any available thread.
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(creation_request_lock_);
|
||||
std::lock_guard<xe_mutex> lock(creation_request_lock_);
|
||||
creation_queue_.push_back(new_pipeline);
|
||||
}
|
||||
creation_request_cond_.notify_one();
|
||||
@@ -3314,7 +3314,7 @@ void PipelineCache::CreationThread(size_t thread_index) {
|
||||
// Check if need to shut down or set the completion event and dequeue the
|
||||
// pipeline if there is any.
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(creation_request_lock_);
|
||||
std::unique_lock<xe_mutex> lock(creation_request_lock_);
|
||||
if (thread_index >= creation_threads_shutdown_from_ ||
|
||||
creation_queue_.empty()) {
|
||||
if (creation_completion_set_event_ && creation_threads_busy_ == 0) {
|
||||
@@ -3345,7 +3345,7 @@ void PipelineCache::CreationThread(size_t thread_index) {
|
||||
// completion event if needed (at the next iteration, or in some other
|
||||
// thread).
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(creation_request_lock_);
|
||||
std::lock_guard<xe_mutex> lock(creation_request_lock_);
|
||||
--creation_threads_busy_;
|
||||
}
|
||||
}
|
||||
@@ -3356,7 +3356,7 @@ void PipelineCache::CreateQueuedPipelinesOnProcessorThread() {
|
||||
while (true) {
|
||||
Pipeline* pipeline_to_create;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(creation_request_lock_);
|
||||
std::lock_guard<xe_mutex> lock(creation_request_lock_);
|
||||
if (creation_queue_.empty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -403,8 +403,8 @@ class PipelineCache {
|
||||
// Pipeline creation threads.
|
||||
void CreationThread(size_t thread_index);
|
||||
void CreateQueuedPipelinesOnProcessorThread();
|
||||
std::mutex creation_request_lock_;
|
||||
std::condition_variable creation_request_cond_;
|
||||
xe_mutex creation_request_lock_;
|
||||
std::condition_variable_any creation_request_cond_;
|
||||
// Protected with creation_request_lock_, notify_one creation_request_cond_
|
||||
// when set.
|
||||
std::deque<Pipeline*> creation_queue_;
|
||||
|
||||
Reference in New Issue
Block a user