135 lines
4.5 KiB
C++
135 lines
4.5 KiB
C++
/**
|
|
******************************************************************************
|
|
* Xenia : Xbox 360 Emulator Research Project *
|
|
******************************************************************************
|
|
* Copyright 2018 Ben Vanik. All rights reserved. *
|
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
******************************************************************************
|
|
*/
|
|
|
|
#ifndef XENIA_GPU_HLSL_SHADER_TRANSLATOR_H_
|
|
#define XENIA_GPU_HLSL_SHADER_TRANSLATOR_H_
|
|
|
|
#include <vector>
|
|
|
|
#include "xenia/base/string_buffer.h"
|
|
#include "xenia/gpu/shader_translator.h"
|
|
|
|
namespace xe {
|
|
namespace gpu {
|
|
|
|
// For shader model 5_1 (Direct3D 12).
|
|
class HlslShaderTranslator : public ShaderTranslator {
|
|
public:
|
|
HlslShaderTranslator();
|
|
~HlslShaderTranslator() override;
|
|
|
|
struct SystemConstants {
|
|
// vec4 0
|
|
float mul_rcp_w[3];
|
|
uint32_t vertex_index_endian;
|
|
// vec4 1
|
|
float ndc_scale[3];
|
|
uint32_t textures_are_3d;
|
|
// vec4 2
|
|
float ndc_offset[3];
|
|
float pixel_half_pixel_offset;
|
|
// vec4 3
|
|
float vertex_half_pixel_offset[2];
|
|
uint32_t pixel_pos_reg;
|
|
// vec4 4
|
|
float ssaa_inv_scale[2];
|
|
};
|
|
|
|
enum class SRVType : uint32_t {
|
|
// 1D, 2D or stacked texture bound as a 2D array texture.
|
|
Texture2DArray,
|
|
// 3D texture (also has a 2D array view of the same fetch registers because
|
|
// tfetch3D is used for both stacked and 3D textures.
|
|
Texture3D,
|
|
// Cube texture.
|
|
TextureCube
|
|
};
|
|
|
|
struct SRVBinding {
|
|
SRVType type : 2;
|
|
// 0-31 for textures, 0-95 for vertex buffers.
|
|
uint32_t fetch_constant : 7;
|
|
};
|
|
|
|
protected:
|
|
void Reset() override;
|
|
|
|
void EmitTranslationError(const char* message) override;
|
|
void EmitUnimplementedTranslationError() override;
|
|
|
|
void StartTranslation() override;
|
|
std::vector<uint8_t> CompleteTranslation() override;
|
|
|
|
void ProcessLabel(uint32_t cf_index) override;
|
|
|
|
void ProcessControlFlowNopInstruction(uint32_t cf_index) override;
|
|
void ProcessControlFlowInstructionBegin(uint32_t cf_index) override;
|
|
void ProcessControlFlowInstructionEnd(uint32_t cf_index) override;
|
|
void ProcessExecInstructionBegin(const ParsedExecInstruction& instr) override;
|
|
void ProcessExecInstructionEnd(const ParsedExecInstruction& instr) override;
|
|
void ProcessLoopStartInstruction(
|
|
const ParsedLoopStartInstruction& instr) override;
|
|
void ProcessLoopEndInstruction(
|
|
const ParsedLoopEndInstruction& instr) override;
|
|
void ProcessCallInstruction(const ParsedCallInstruction& instr) override;
|
|
void ProcessReturnInstruction(const ParsedReturnInstruction& instr) override;
|
|
void ProcessJumpInstruction(const ParsedJumpInstruction& instr) override;
|
|
void ProcessAllocInstruction(const ParsedAllocInstruction& instr) override;
|
|
|
|
void ProcessVertexFetchInstruction(
|
|
const ParsedVertexFetchInstruction& instr) override;
|
|
void ProcessTextureFetchInstruction(
|
|
const ParsedTextureFetchInstruction& instr) override;
|
|
void ProcessAluInstruction(const ParsedAluInstruction& instr) override;
|
|
|
|
private:
|
|
void Indent();
|
|
void Unindent();
|
|
|
|
// Returns whether a new conditional was emitted.
|
|
bool BeginPredicatedInstruction(bool is_predicated, bool predicate_condition);
|
|
void EndPredicatedInstruction(bool conditional_emitted);
|
|
|
|
void EmitLoadOperand(size_t src_index, const InstructionOperand& op);
|
|
void EmitStoreResult(const InstructionResult& result, bool source_is_scalar);
|
|
|
|
StringBuffer source_inner_;
|
|
uint32_t depth_ = 0;
|
|
char depth_prefix_[32] = {0};
|
|
|
|
bool cf_wrote_pc_ = false;
|
|
bool cf_exec_pred_ = false;
|
|
bool cf_exec_pred_cond_ = false;
|
|
|
|
bool writes_depth_ = false;
|
|
|
|
std::vector<SRVBinding> srv_bindings_;
|
|
// Finds or adds an SRV binding to the shader's SRV list, returns t# index.
|
|
uint32_t AddSRVBinding(SRVType type, uint32_t fetch_constant);
|
|
|
|
// Sampler index -> fetch constant index mapping.
|
|
// TODO(Triang3l): On binding tier 1 (Nvidia Fermi), there can't be more than
|
|
// 16 samplers in a shader. Hopefully no game uses so many.
|
|
uint32_t sampler_fetch_constants_[32];
|
|
uint32_t sampler_count_ = 0;
|
|
uint32_t AddSampler(uint32_t fetch_constant);
|
|
|
|
void ProcessVectorAluInstruction(const ParsedAluInstruction& instr);
|
|
void ProcessScalarAluInstruction(const ParsedAluInstruction& instr);
|
|
|
|
// Whether the cube instruction has been used and conversion functions need to
|
|
// be emitted.
|
|
bool cube_used_ = false;
|
|
};
|
|
|
|
} // namespace gpu
|
|
} // namespace xe
|
|
|
|
#endif // XENIA_GPU_HLSL_SHADER_TRANSLATOR_H_
|