Copying over the shader translator - generating d3d shaders now.

This commit is contained in:
Ben Vanik 2014-12-27 00:42:15 -08:00
parent 6573c87b8d
commit 58cff84550
9 changed files with 1841 additions and 30 deletions

View File

@ -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

View File

@ -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();

View File

@ -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:

View File

@ -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

View File

@ -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_

View File

@ -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',
], ],

View File

@ -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;

View File

@ -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) | \