Files
Xenia-Canary/src/xenia/gpu/shader_translator.h
chss95cs@gmail.com 8f7f7dc6ad fixed wine crash from use of NtSetEventPriorityBoost
add xe::clear_lowest_bit, use it in place of shift-andnot in some bit iteration code
make is_allocated_ and is_enabled_ volatile in xma_context
preallocate avpacket buffer in XMAContext::Setup, the reallocations of the buffer in ffmpeg were showing up on profiles
check is_enabled and is_allocated BEFORE locking an xmacontext. XMA worker was spending most of its time locking and unlocking contexts
Removed XeDMAC, dma:: namespace. It was a bad idea and I couldn't make it work in the end. Kept vastcpy and moved it to the memory namespace instead
Made the rest of global_critical_region's members static. They never needed an instance.
Removed ifdef'ed out code from ring_buffer.h
Added EventInfo struct to threading, added Event::Query to aid with implementing NtQueryEvent.
Removed vector from WaitMultiple, instead use a fixed array of 64 handles that we populate. WaitForMultipleObjects cannot handle more than 64 objects.
Remove XE_MSVC_OPTIMIZE_SMALL() use in x64_sequences, x64 backend is now always size optimized because of premake
Make global_critical_region_ static constexpr in shared_memory.h to get rid of wasteage of 8 bytes (empty class=1byte, +alignment for next member=8)
Move trace-related data to the tail of SharedMemory to keep more important data together
In IssueDraw build an array of fetch constant addresses/sizes, then pre-lock the global lock before doing requestrange for each instead of individually locking within requestrange for each of them
Consistent access specifier protected for pm4_command_processor_declare
Devirtualize WriteOneRegisterFromRing.
Move ExecutePacket and ExecutePrimaryBuffer to pm4_command_buffer_x
Remove many redundant header inclusions access xenia-gpu
Minor microoptimization of ExecutePacketType0

Add TextureCache::RequestTextures for batch invocation of LoadTexturesData

Add TextureCache::LoadTexturesData for reducing the number of times we release and reacquire the global lock.
Ideally you should hold the global lock for as little time as possible, but if you are constantly acquiring and releasing it you are actually more likely to have contention
Add already_locked param to ObjectTable::LookupObject to help with reducing lock acquire/release pairs
Add missing checks to XAudioRegisterRenderDriverClient_entry. this is unlikely to fix anything, it was just an easy thing to do
Add NtQueryEvent system call implementation. I don't actually know of any games that need it.
Instead of using std::vector + push_back in KeWaitForMultipleObjects and xeNtWaitForMultipleObjectsEx use a fixed size array of 64 and track the count. More than 64 objects is not permitted by the kernel. The repeated reallocations from push_back were appearing unusually high on the profiler, but were masked until now by waitformultipleobjects natural overhead
Pre-lock the global lock before looking up each handle for xeNtWaitForMultipleObjectsEx and KeWaitForMultipleObjects.
Pre-lock before looking up the signal and waiter in NtSignalAndWaitForSingleObjectEx
add missing checks to NtWaitForMultipleObjectsEx
Support pre-locking in XObject::GetNativeObject
2022-10-08 09:55:17 -07:00

157 lines
6.1 KiB
C++

/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2015 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_GPU_SHADER_TRANSLATOR_H_
#define XENIA_GPU_SHADER_TRANSLATOR_H_
#include <memory>
#include "xenia/gpu/shader.h"
namespace xe {
namespace gpu {
class ShaderTranslator {
public:
virtual ~ShaderTranslator();
virtual uint64_t GetDefaultVertexShaderModification(
uint32_t dynamic_addressable_register_count,
Shader::HostVertexShaderType host_vertex_shader_type =
Shader::HostVertexShaderType::kVertex) const {
return 0;
}
virtual uint64_t GetDefaultPixelShaderModification(
uint32_t dynamic_addressable_register_count) const {
return 0;
}
// AnalyzeUcode must be done on the shader before translating!
bool TranslateAnalyzedShader(Shader::Translation& translation);
protected:
ShaderTranslator();
// Resets translator state before beginning translation.
virtual void Reset();
// Shader and modification currently being translated.
Shader::Translation& current_translation() const { return *translation_; }
Shader& current_shader() const { return current_translation().shader(); }
// Register count from SQ_PROGRAM_CNTL, stored by the implementation in its
// modification bits.
virtual uint32_t GetModificationRegisterCount() const {
return xenos::kMaxShaderTempRegisters;
}
// True if the current shader is a vertex shader.
bool is_vertex_shader() const {
return current_shader().type() == xenos::ShaderType::kVertex;
}
// True if the current shader is a pixel shader.
bool is_pixel_shader() const {
return current_shader().type() == xenos::ShaderType::kPixel;
}
// Temporary register count, accessible via static and dynamic addressing.
uint32_t register_count() const { return register_count_; }
// Emits a translation error that will be passed back in the result.
virtual void EmitTranslationError(const char* message, bool is_fatal = true);
// Handles the start of translation.
// At this point the vertex and texture bindings have been gathered.
virtual void StartTranslation() {}
// Handles the end of translation when all ucode has been processed.
// Returns the translated shader binary.
virtual std::vector<uint8_t> CompleteTranslation() {
return std::vector<uint8_t>();
}
// Handles post-translation tasks when the shader has been fully translated.
virtual void PostTranslation() {}
// Sets the host disassembly on a shader.
void set_host_disassembly(Shader::Translation& translation,
std::string value) {
translation.host_disassembly_ = std::move(value);
}
// Pre-process a control-flow instruction before anything else.
virtual void PreProcessControlFlowInstructions(
std::vector<ucode::ControlFlowInstruction> instrs) {}
// Handles translation for control flow label addresses.
// This is triggered once for each label required (due to control flow
// operations) before any of the instructions within the target exec.
virtual void ProcessLabel(uint32_t cf_index) {}
// Handles translation for control flow nop instructions.
virtual void ProcessControlFlowNopInstruction(uint32_t cf_index) {}
// Handles the start of a control flow instruction at the given address.
virtual void ProcessControlFlowInstructionBegin(uint32_t cf_index) {}
// Handles the end of a control flow instruction that began at the given
// address.
virtual void ProcessControlFlowInstructionEnd(uint32_t cf_index) {}
// Handles translation for control flow exec instructions prior to their
// contained ALU/fetch instructions.
virtual void ProcessExecInstructionBegin(const ParsedExecInstruction& instr) {
}
// Handles translation for control flow exec instructions after their
// contained ALU/fetch instructions.
virtual void ProcessExecInstructionEnd(const ParsedExecInstruction& instr) {}
// Handles translation for loop start instructions.
virtual void ProcessLoopStartInstruction(
const ParsedLoopStartInstruction& instr) {}
// Handles translation for loop end instructions.
virtual void ProcessLoopEndInstruction(
const ParsedLoopEndInstruction& instr) {}
// Handles translation for function call instructions.
virtual void ProcessCallInstruction(const ParsedCallInstruction& instr) {}
// Handles translation for function return instructions.
virtual void ProcessReturnInstruction(const ParsedReturnInstruction& instr) {}
// Handles translation for jump instructions.
virtual void ProcessJumpInstruction(const ParsedJumpInstruction& instr) {}
// Handles translation for alloc instructions.
virtual void ProcessAllocInstruction(const ParsedAllocInstruction& instr) {}
// Handles translation for vertex fetch instructions.
virtual void ProcessVertexFetchInstruction(
const ParsedVertexFetchInstruction& instr) {}
// Handles translation for texture fetch instructions.
virtual void ProcessTextureFetchInstruction(
const ParsedTextureFetchInstruction& instr) {}
// Handles translation for ALU instructions.
virtual void ProcessAluInstruction(const ParsedAluInstruction& instr) {}
private:
void TranslateControlFlowInstruction(const ucode::ControlFlowInstruction& cf);
void TranslateExecInstructions(const ParsedExecInstruction& instr);
// Current shader and modification being translated.
Shader::Translation* translation_ = nullptr;
// Accumulated translation errors.
std::vector<Shader::Error> errors_;
// Temporary register count, accessible via static and dynamic addressing.
uint32_t register_count_ = 0;
// Current control flow dword index.
uint32_t cf_index_ = 0;
// Kept for supporting vfetch_mini.
ucode::VertexFetchInstruction previous_vfetch_full_;
};
} // namespace gpu
} // namespace xe
#endif // XENIA_GPU_SHADER_TRANSLATOR_H_