Copying over the shader translator - generating d3d shaders now.
This commit is contained in:
parent
6573c87b8d
commit
58cff84550
|
@ -62,6 +62,8 @@ void StringBuffer::AppendBytes(const uint8_t* buffer, size_t length) {
|
||||||
|
|
||||||
const char* StringBuffer::GetString() const { return buffer_.data(); }
|
const char* StringBuffer::GetString() const { return buffer_.data(); }
|
||||||
|
|
||||||
|
std::string StringBuffer::to_string() { return std::string(buffer_.data()); }
|
||||||
|
|
||||||
char* StringBuffer::ToString() { return strdup(buffer_.data()); }
|
char* StringBuffer::ToString() { return strdup(buffer_.data()); }
|
||||||
|
|
||||||
} // namespace alloy
|
} // namespace alloy
|
||||||
|
|
|
@ -31,6 +31,7 @@ class StringBuffer {
|
||||||
void AppendBytes(const uint8_t* buffer, size_t length);
|
void AppendBytes(const uint8_t* buffer, size_t length);
|
||||||
|
|
||||||
const char* GetString() const;
|
const char* GetString() const;
|
||||||
|
std::string to_string();
|
||||||
char* ToString();
|
char* ToString();
|
||||||
char* EncodeBase64();
|
char* EncodeBase64();
|
||||||
|
|
||||||
|
|
|
@ -1839,82 +1839,53 @@ bool CommandProcessor::PopulateVertexBuffers(DrawCommand* draw_command) {
|
||||||
uint32_t el_index = 0;
|
uint32_t el_index = 0;
|
||||||
for (uint32_t i = 0; i < desc.element_count; ++i) {
|
for (uint32_t i = 0; i < desc.element_count; ++i) {
|
||||||
const auto& el = desc.elements[i];
|
const auto& el = desc.elements[i];
|
||||||
GLuint comp_count;
|
auto comp_count = GetVertexFormatComponentCount(el.format);
|
||||||
GLuint comp_size;
|
|
||||||
GLenum comp_type;
|
GLenum comp_type;
|
||||||
switch (el.format) {
|
switch (el.format) {
|
||||||
case VertexFormat::k_8_8_8_8:
|
case VertexFormat::k_8_8_8_8:
|
||||||
comp_count = 4;
|
|
||||||
comp_size = 1;
|
|
||||||
comp_type = el.is_signed ? GL_BYTE : GL_UNSIGNED_BYTE;
|
comp_type = el.is_signed ? GL_BYTE : GL_UNSIGNED_BYTE;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_2_10_10_10:
|
case VertexFormat::k_2_10_10_10:
|
||||||
comp_count = 4;
|
|
||||||
comp_size = 4;
|
|
||||||
comp_type = el.is_signed ? GL_INT_2_10_10_10_REV
|
comp_type = el.is_signed ? GL_INT_2_10_10_10_REV
|
||||||
: GL_UNSIGNED_INT_2_10_10_10_REV;
|
: GL_UNSIGNED_INT_2_10_10_10_REV;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_10_11_11:
|
case VertexFormat::k_10_11_11:
|
||||||
comp_count = 3;
|
|
||||||
comp_size = 4;
|
|
||||||
assert_false(el.is_signed);
|
assert_false(el.is_signed);
|
||||||
comp_type = GL_UNSIGNED_INT_10F_11F_11F_REV;
|
comp_type = GL_UNSIGNED_INT_10F_11F_11F_REV;
|
||||||
break;
|
break;
|
||||||
/*case VertexFormat::k_11_11_10:
|
/*case VertexFormat::k_11_11_10:
|
||||||
break;*/
|
break;*/
|
||||||
case VertexFormat::k_16_16:
|
case VertexFormat::k_16_16:
|
||||||
comp_count = 2;
|
|
||||||
comp_size = 2;
|
|
||||||
comp_type = el.is_signed ? GL_SHORT : GL_UNSIGNED_SHORT;
|
comp_type = el.is_signed ? GL_SHORT : GL_UNSIGNED_SHORT;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_16_16_FLOAT:
|
case VertexFormat::k_16_16_FLOAT:
|
||||||
comp_count = 2;
|
|
||||||
comp_size = 2;
|
|
||||||
comp_type = GL_HALF_FLOAT;
|
comp_type = GL_HALF_FLOAT;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_16_16_16_16:
|
case VertexFormat::k_16_16_16_16:
|
||||||
comp_count = 4;
|
|
||||||
comp_size = 2;
|
|
||||||
comp_type = el.is_signed ? GL_SHORT : GL_UNSIGNED_SHORT;
|
comp_type = el.is_signed ? GL_SHORT : GL_UNSIGNED_SHORT;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_16_16_16_16_FLOAT:
|
case VertexFormat::k_16_16_16_16_FLOAT:
|
||||||
comp_count = 4;
|
|
||||||
comp_size = 2;
|
|
||||||
comp_type = GL_HALF_FLOAT;
|
comp_type = GL_HALF_FLOAT;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_32:
|
case VertexFormat::k_32:
|
||||||
comp_count = 1;
|
|
||||||
comp_size = 4;
|
|
||||||
comp_type = el.is_signed ? GL_INT : GL_UNSIGNED_INT;
|
comp_type = el.is_signed ? GL_INT : GL_UNSIGNED_INT;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_32_32:
|
case VertexFormat::k_32_32:
|
||||||
comp_count = 2;
|
|
||||||
comp_size = 4;
|
|
||||||
comp_type = el.is_signed ? GL_INT : GL_UNSIGNED_INT;
|
comp_type = el.is_signed ? GL_INT : GL_UNSIGNED_INT;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_32_32_32_32:
|
case VertexFormat::k_32_32_32_32:
|
||||||
comp_count = 4;
|
|
||||||
comp_size = 4;
|
|
||||||
comp_type = el.is_signed ? GL_INT : GL_UNSIGNED_INT;
|
comp_type = el.is_signed ? GL_INT : GL_UNSIGNED_INT;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_32_FLOAT:
|
case VertexFormat::k_32_FLOAT:
|
||||||
comp_count = 1;
|
|
||||||
comp_size = 4;
|
|
||||||
comp_type = GL_FLOAT;
|
comp_type = GL_FLOAT;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_32_32_FLOAT:
|
case VertexFormat::k_32_32_FLOAT:
|
||||||
comp_count = 2;
|
|
||||||
comp_size = 4;
|
|
||||||
comp_type = GL_FLOAT;
|
comp_type = GL_FLOAT;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_32_32_32_FLOAT:
|
case VertexFormat::k_32_32_32_FLOAT:
|
||||||
comp_count = 3;
|
|
||||||
comp_size = 4;
|
|
||||||
comp_type = GL_FLOAT;
|
comp_type = GL_FLOAT;
|
||||||
break;
|
break;
|
||||||
case VertexFormat::k_32_32_32_32_FLOAT:
|
case VertexFormat::k_32_32_32_32_FLOAT:
|
||||||
comp_count = 4;
|
|
||||||
comp_size = 4;
|
|
||||||
comp_type = GL_FLOAT;
|
comp_type = GL_FLOAT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <xenia/gpu/gl4/gl4_shader.h>
|
#include <xenia/gpu/gl4/gl4_shader.h>
|
||||||
|
|
||||||
#include <poly/math.h>
|
#include <poly/math.h>
|
||||||
|
#include <xenia/gpu/gl4/gl4_shader_translator.h>
|
||||||
#include <xenia/gpu/gpu-private.h>
|
#include <xenia/gpu/gpu-private.h>
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
@ -18,6 +19,9 @@ namespace gl4 {
|
||||||
|
|
||||||
extern "C" GLEWContext* glewGetContext();
|
extern "C" GLEWContext* glewGetContext();
|
||||||
|
|
||||||
|
// Stateful, but minimally.
|
||||||
|
thread_local GL4ShaderTranslator shader_translator_;
|
||||||
|
|
||||||
GL4Shader::GL4Shader(ShaderType shader_type, uint64_t data_hash,
|
GL4Shader::GL4Shader(ShaderType shader_type, uint64_t data_hash,
|
||||||
const uint32_t* dword_ptr, uint32_t dword_count)
|
const uint32_t* dword_ptr, uint32_t dword_count)
|
||||||
: Shader(shader_type, data_hash, dword_ptr, dword_count), program_(0) {}
|
: Shader(shader_type, data_hash, dword_ptr, dword_count), program_(0) {}
|
||||||
|
@ -106,6 +110,13 @@ bool GL4Shader::PrepareVertexShader(
|
||||||
//" gl_Position = oPos;\n"
|
//" gl_Position = oPos;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
std::string translated_source =
|
||||||
|
shader_translator_.TranslateVertexShader(this, program_cntl);
|
||||||
|
if (translated_source.empty()) {
|
||||||
|
PLOGE("Vertex shader failed translation");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!CompileProgram(source)) {
|
if (!CompileProgram(source)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -133,6 +144,13 @@ bool GL4Shader::PreparePixelShader(
|
||||||
//" gl_FragDepth = 0.0;\n"
|
//" gl_FragDepth = 0.0;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
std::string translated_source = shader_translator_.TranslatePixelShader(
|
||||||
|
this, program_cntl, vertex_shader->alloc_counts());
|
||||||
|
if (translated_source.empty()) {
|
||||||
|
PLOGE("Pixel shader failed translation");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!CompileProgram(source)) {
|
if (!CompileProgram(source)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,123 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_GPU_GL4_GL4_SHADER_TRANSLATOR_H_
|
||||||
|
#define XENIA_GPU_GL4_GL4_SHADER_TRANSLATOR_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <alloy/string_buffer.h>
|
||||||
|
#include <xenia/common.h>
|
||||||
|
#include <xenia/gpu/gl4/gl_context.h>
|
||||||
|
#include <xenia/gpu/gl4/gl4_shader.h>
|
||||||
|
#include <xenia/gpu/ucode.h>
|
||||||
|
#include <xenia/gpu/xenos.h>
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace gpu {
|
||||||
|
namespace gl4 {
|
||||||
|
|
||||||
|
class GL4ShaderTranslator {
|
||||||
|
public:
|
||||||
|
static const uint32_t kMaxInterpolators = 16;
|
||||||
|
|
||||||
|
GL4ShaderTranslator();
|
||||||
|
~GL4ShaderTranslator();
|
||||||
|
|
||||||
|
std::string TranslateVertexShader(
|
||||||
|
GL4Shader* vertex_shader,
|
||||||
|
const xenos::xe_gpu_program_cntl_t& program_cntl);
|
||||||
|
std::string TranslatePixelShader(
|
||||||
|
GL4Shader* pixel_shader, const xenos::xe_gpu_program_cntl_t& program_cntl,
|
||||||
|
const GL4Shader::AllocCounts& alloc_counts);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ShaderType shader_type_;
|
||||||
|
uint32_t tex_fetch_index_;
|
||||||
|
const uint32_t* dwords_;
|
||||||
|
|
||||||
|
static const int kOutputCapacity = 64 * 1024;
|
||||||
|
alloy::StringBuffer output_;
|
||||||
|
|
||||||
|
bool is_vertex_shader() const { return shader_type_ == ShaderType::kVertex; }
|
||||||
|
bool is_pixel_shader() const { return shader_type_ == ShaderType::kPixel; }
|
||||||
|
|
||||||
|
void Reset(GL4Shader* shader);
|
||||||
|
void Append(const char* format, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
output_.AppendVarargs(format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppendTextureHeader(const GL4Shader::SamplerInputs& sampler_inputs);
|
||||||
|
|
||||||
|
void AppendSrcReg(uint32_t num, uint32_t type, uint32_t swiz, uint32_t negate,
|
||||||
|
uint32_t abs);
|
||||||
|
void AppendDestRegName(uint32_t num, uint32_t dst_exp);
|
||||||
|
void AppendDestReg(uint32_t num, uint32_t mask, uint32_t dst_exp);
|
||||||
|
void AppendDestRegPost(uint32_t num, uint32_t mask, uint32_t dst_exp);
|
||||||
|
void PrintSrcReg(uint32_t num, uint32_t type, uint32_t swiz, uint32_t negate,
|
||||||
|
uint32_t abs);
|
||||||
|
void PrintDstReg(uint32_t num, uint32_t mask, uint32_t dst_exp);
|
||||||
|
void PrintExportComment(uint32_t num);
|
||||||
|
|
||||||
|
bool TranslateALU(const ucode::instr_alu_t* alu, int sync);
|
||||||
|
bool TranslateALU_ADDv(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_MULv(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_MAXv(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_MINv(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_SETXXv(const ucode::instr_alu_t& alu, const char* op);
|
||||||
|
bool TranslateALU_SETEv(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_SETGTv(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_SETGTEv(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_SETNEv(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_FRACv(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_TRUNCv(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_FLOORv(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_MULADDv(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_CNDXXv(const ucode::instr_alu_t& alu, const char* op);
|
||||||
|
bool TranslateALU_CNDEv(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_CNDGTEv(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_CNDGTv(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_DOT4v(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_DOT3v(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_DOT2ADDv(const ucode::instr_alu_t& alu);
|
||||||
|
// CUBEv
|
||||||
|
bool TranslateALU_MAX4v(const ucode::instr_alu_t& alu);
|
||||||
|
// ...
|
||||||
|
bool TranslateALU_MAXs(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_MINs(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_SETXXs(const ucode::instr_alu_t& alu, const char* op);
|
||||||
|
bool TranslateALU_SETEs(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_SETGTs(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_SETGTEs(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_SETNEs(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_RECIP_IEEE(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_MUL_CONST_0(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_MUL_CONST_1(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_ADD_CONST_0(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_ADD_CONST_1(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_SUB_CONST_0(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_SUB_CONST_1(const ucode::instr_alu_t& alu);
|
||||||
|
bool TranslateALU_RETAIN_PREV(const ucode::instr_alu_t& alu);
|
||||||
|
|
||||||
|
void PrintDestFecth(uint32_t dst_reg, uint32_t dst_swiz);
|
||||||
|
void AppendFetchDest(uint32_t dst_reg, uint32_t dst_swiz);
|
||||||
|
|
||||||
|
bool TranslateExec(const ucode::instr_cf_exec_t& cf);
|
||||||
|
bool TranslateVertexFetch(const ucode::instr_fetch_vtx_t* vtx, int sync);
|
||||||
|
bool TranslateTextureFetch(const ucode::instr_fetch_tex_t* tex, int sync);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gl4
|
||||||
|
} // namespace gpu
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
#endif // XENIA_GPU_GL4_GL4_SHADER_TRANSLATOR_H_
|
|
@ -12,6 +12,8 @@
|
||||||
'gl4_graphics_system.h',
|
'gl4_graphics_system.h',
|
||||||
'gl4_shader.cc',
|
'gl4_shader.cc',
|
||||||
'gl4_shader.h',
|
'gl4_shader.h',
|
||||||
|
'gl4_shader_translator.cc',
|
||||||
|
'gl4_shader_translator.h',
|
||||||
'gl_context.cc',
|
'gl_context.cc',
|
||||||
'gl_context.h',
|
'gl_context.h',
|
||||||
],
|
],
|
||||||
|
|
|
@ -30,6 +30,8 @@ class Shader {
|
||||||
return translated_disassembly_;
|
return translated_disassembly_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint32_t* data() const { return data_.data(); }
|
||||||
|
|
||||||
struct BufferDescElement {
|
struct BufferDescElement {
|
||||||
ucode::instr_fetch_vtx_t vtx_fetch;
|
ucode::instr_fetch_vtx_t vtx_fetch;
|
||||||
xenos::VertexFormat format;
|
xenos::VertexFormat format;
|
||||||
|
|
|
@ -140,6 +140,36 @@ enum class VertexFormat : uint32_t {
|
||||||
k_32_32_32_32_FLOAT = 38,
|
k_32_32_32_32_FLOAT = 38,
|
||||||
k_32_32_32_FLOAT = 57,
|
k_32_32_32_FLOAT = 57,
|
||||||
};
|
};
|
||||||
|
inline int GetVertexFormatComponentCount(VertexFormat format) {
|
||||||
|
switch (format) {
|
||||||
|
case VertexFormat::k_32:
|
||||||
|
case VertexFormat::k_32_FLOAT:
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_16_16:
|
||||||
|
case VertexFormat::k_16_16_FLOAT:
|
||||||
|
case VertexFormat::k_32_32:
|
||||||
|
case VertexFormat::k_32_32_FLOAT:
|
||||||
|
return 2;
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_10_11_11:
|
||||||
|
case VertexFormat::k_11_11_10:
|
||||||
|
case VertexFormat::k_32_32_32_FLOAT:
|
||||||
|
return 3;
|
||||||
|
break;
|
||||||
|
case VertexFormat::k_8_8_8_8:
|
||||||
|
case VertexFormat::k_2_10_10_10:
|
||||||
|
case VertexFormat::k_16_16_16_16:
|
||||||
|
case VertexFormat::k_16_16_16_16_FLOAT:
|
||||||
|
case VertexFormat::k_32_32_32_32:
|
||||||
|
case VertexFormat::k_32_32_32_32_FLOAT:
|
||||||
|
return 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert_unhandled_case(format);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define XE_GPU_MAKE_SWIZZLE(x, y, z, w) \
|
#define XE_GPU_MAKE_SWIZZLE(x, y, z, w) \
|
||||||
(((XE_GPU_SWIZZLE_##x) << 0) | ((XE_GPU_SWIZZLE_##y) << 3) | \
|
(((XE_GPU_SWIZZLE_##x) << 0) | ((XE_GPU_SWIZZLE_##y) << 3) | \
|
||||||
|
|
Loading…
Reference in New Issue