Replacing old Shader with TranslatedShader.
This commit is contained in:
@@ -491,12 +491,21 @@ Shader* GL4CommandProcessor::LoadShader(ShaderType shader_type,
|
||||
|
||||
// Perform translation.
|
||||
// If this fails the shader will be marked as invalid and ignored later.
|
||||
shader_ptr->Prepare(&shader_translator_);
|
||||
if (shader_translator_.Translate(shader_ptr)) {
|
||||
shader_ptr->Prepare();
|
||||
|
||||
// Dump shader files if desired.
|
||||
if (!FLAGS_dump_shaders.empty()) {
|
||||
shader_ptr->Dump(FLAGS_dump_shaders, "gl4");
|
||||
}
|
||||
} else {
|
||||
XELOGE("Shader failed translation");
|
||||
}
|
||||
|
||||
XELOGGPU("Set %s shader at %0.8X (%db):\n%s",
|
||||
shader_type == ShaderType::kVertex ? "vertex" : "pixel",
|
||||
guest_address, dword_count * 4,
|
||||
shader_ptr->translated_shader()->ucode_disassembly().c_str());
|
||||
shader_ptr->ucode_disassembly().c_str());
|
||||
}
|
||||
return shader_ptr;
|
||||
}
|
||||
@@ -779,7 +788,6 @@ GL4CommandProcessor::UpdateStatus GL4CommandProcessor::UpdateRenderTargets() {
|
||||
// Note that write mask may be more permissive than we want, so we mix that
|
||||
// with the actual targets the pixel shader writes to.
|
||||
GLenum draw_buffers[4] = {GL_NONE, GL_NONE, GL_NONE, GL_NONE};
|
||||
auto pixel_shader = active_pixel_shader_->translated_shader();
|
||||
GLuint color_targets[4] = {kAnyTarget, kAnyTarget, kAnyTarget, kAnyTarget};
|
||||
if (enable_mode == ModeControl::kColorDepth) {
|
||||
uint32_t color_info[4] = {
|
||||
@@ -789,7 +797,7 @@ GL4CommandProcessor::UpdateStatus GL4CommandProcessor::UpdateRenderTargets() {
|
||||
// A2XX_RB_COLOR_MASK_WRITE_* == D3DRS_COLORWRITEENABLE
|
||||
for (int n = 0; n < xe::countof(color_info); n++) {
|
||||
uint32_t write_mask = (regs.rb_color_mask >> (n * 4)) & 0xF;
|
||||
if (!write_mask || !pixel_shader->writes_color_target(n)) {
|
||||
if (!write_mask || !active_pixel_shader_->writes_color_target(n)) {
|
||||
// Unused, so keep disabled and set to wildcard so we'll take any
|
||||
// framebuffer that has it.
|
||||
continue;
|
||||
@@ -1362,9 +1370,7 @@ GL4CommandProcessor::UpdateStatus GL4CommandProcessor::PopulateVertexBuffers() {
|
||||
auto& regs = *register_file_;
|
||||
assert_not_null(active_vertex_shader_);
|
||||
|
||||
const auto& vertex_bindings =
|
||||
active_vertex_shader_->translated_shader()->vertex_bindings();
|
||||
for (const auto& vertex_binding : vertex_bindings) {
|
||||
for (const auto& vertex_binding : active_vertex_shader_->vertex_bindings()) {
|
||||
int r = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 +
|
||||
(vertex_binding.fetch_constant / 3) * 6;
|
||||
const auto group = reinterpret_cast<xe_gpu_fetch_group_t*>(®s.values[r]);
|
||||
@@ -1434,9 +1440,7 @@ GL4CommandProcessor::UpdateStatus GL4CommandProcessor::PopulateSamplers() {
|
||||
bool has_setup_sampler[32] = {false};
|
||||
|
||||
// Vertex texture samplers.
|
||||
const auto& vertex_sampler_inputs =
|
||||
active_vertex_shader_->translated_shader()->texture_bindings();
|
||||
for (auto& texture_binding : vertex_sampler_inputs) {
|
||||
for (auto& texture_binding : active_vertex_shader_->texture_bindings()) {
|
||||
if (has_setup_sampler[texture_binding.fetch_constant]) {
|
||||
continue;
|
||||
}
|
||||
@@ -1450,9 +1454,7 @@ GL4CommandProcessor::UpdateStatus GL4CommandProcessor::PopulateSamplers() {
|
||||
}
|
||||
|
||||
// Pixel shader texture sampler.
|
||||
const auto& pixel_sampler_inputs =
|
||||
active_pixel_shader_->translated_shader()->texture_bindings();
|
||||
for (auto& texture_binding : pixel_sampler_inputs) {
|
||||
for (auto& texture_binding : active_pixel_shader_->texture_bindings()) {
|
||||
if (has_setup_sampler[texture_binding.fetch_constant]) {
|
||||
continue;
|
||||
}
|
||||
@@ -1469,7 +1471,7 @@ GL4CommandProcessor::UpdateStatus GL4CommandProcessor::PopulateSamplers() {
|
||||
}
|
||||
|
||||
GL4CommandProcessor::UpdateStatus GL4CommandProcessor::PopulateSampler(
|
||||
const TranslatedShader::TextureBinding& texture_binding) {
|
||||
const Shader::TextureBinding& texture_binding) {
|
||||
auto& regs = *register_file_;
|
||||
int r = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 +
|
||||
texture_binding.fetch_constant * 6;
|
||||
|
||||
@@ -123,8 +123,7 @@ class GL4CommandProcessor : public CommandProcessor {
|
||||
UpdateStatus PopulateIndexBuffer(IndexBufferInfo* index_buffer_info);
|
||||
UpdateStatus PopulateVertexBuffers();
|
||||
UpdateStatus PopulateSamplers();
|
||||
UpdateStatus PopulateSampler(
|
||||
const TranslatedShader::TextureBinding& texture_binding);
|
||||
UpdateStatus PopulateSampler(const Shader::TextureBinding& texture_binding);
|
||||
bool IssueCopy() override;
|
||||
|
||||
CachedFramebuffer* GetFramebuffer(GLuint color_targets[4],
|
||||
|
||||
@@ -9,11 +9,8 @@
|
||||
|
||||
#include "xenia/gpu/gl4/gl4_shader.h"
|
||||
|
||||
#include "xenia/base/filesystem.h"
|
||||
#include "xenia/base/logging.h"
|
||||
#include "xenia/base/math.h"
|
||||
#include "xenia/gpu/gl4/gl4_gpu_flags.h"
|
||||
#include "xenia/gpu/gpu_flags.h"
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
@@ -30,8 +27,8 @@ GL4Shader::~GL4Shader() {
|
||||
glDeleteVertexArrays(1, &vao_);
|
||||
}
|
||||
|
||||
bool GL4Shader::Prepare(ShaderTranslator* shader_translator) {
|
||||
if (!Shader::Prepare(shader_translator)) {
|
||||
bool GL4Shader::Prepare() {
|
||||
if (!Shader::Prepare()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -51,7 +48,7 @@ bool GL4Shader::Prepare(ShaderTranslator* shader_translator) {
|
||||
bool GL4Shader::PrepareVertexArrayObject() {
|
||||
glCreateVertexArrays(1, &vao_);
|
||||
|
||||
for (const auto& vertex_binding : translated_shader_->vertex_bindings()) {
|
||||
for (const auto& vertex_binding : vertex_bindings()) {
|
||||
for (const auto& attrib : vertex_binding.attributes) {
|
||||
auto comp_count = GetVertexFormatComponentCount(
|
||||
attrib.fetch_instr.attributes.data_format);
|
||||
@@ -126,43 +123,8 @@ bool GL4Shader::PrepareVertexArrayObject() {
|
||||
bool GL4Shader::CompileProgram() {
|
||||
assert_zero(program_);
|
||||
|
||||
auto source_str = translated_shader_->GetBinaryString();
|
||||
|
||||
// Save to disk, if we asked for it.
|
||||
auto base_path = FLAGS_dump_shaders.c_str();
|
||||
char file_name[kMaxPath];
|
||||
snprintf(file_name, xe::countof(file_name), "%s/gl4_gen_%.16llX.%s",
|
||||
base_path, data_hash_,
|
||||
shader_type_ == ShaderType::kVertex ? "vert" : "frag");
|
||||
if (!FLAGS_dump_shaders.empty()) {
|
||||
// Ensure shader dump path exists.
|
||||
auto dump_shaders_path = xe::to_wstring(FLAGS_dump_shaders);
|
||||
if (!dump_shaders_path.empty()) {
|
||||
dump_shaders_path = xe::to_absolute_path(dump_shaders_path);
|
||||
xe::filesystem::CreateFolder(dump_shaders_path);
|
||||
}
|
||||
|
||||
char bin_file_name[kMaxPath];
|
||||
snprintf(bin_file_name, xe::countof(file_name), "%s/gl4_gen_%.16llX.bin.%s",
|
||||
base_path, data_hash_,
|
||||
shader_type_ == ShaderType::kVertex ? "vert" : "frag");
|
||||
FILE* f = fopen(bin_file_name, "w");
|
||||
if (f) {
|
||||
fwrite(data_.data(), 4, data_.size(), f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
// Note that we put the translated source first so we get good line numbers.
|
||||
f = fopen(file_name, "w");
|
||||
if (f) {
|
||||
fprintf(f, "%s", source_str.c_str());
|
||||
fprintf(f, "/*\n");
|
||||
fprintf(f, "%s", translated_shader_->ucode_disassembly().c_str());
|
||||
fprintf(f, " */\n");
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
// Give source to GL.
|
||||
auto source_str = GetTranslatedBinaryString();
|
||||
auto source_str_ptr = source_str.c_str();
|
||||
program_ = glCreateShaderProgramv(shader_type_ == ShaderType::kVertex
|
||||
? GL_VERTEX_SHADER
|
||||
@@ -185,7 +147,7 @@ bool GL4Shader::CompileProgram() {
|
||||
glGetProgramInfoLog(program_, log_length, &log_length,
|
||||
const_cast<char*>(info_log.data()));
|
||||
XELOGE("Unable to link program: %s", info_log.c_str());
|
||||
error_log_ = std::move(info_log);
|
||||
host_error_log_ = std::move(info_log);
|
||||
assert_always("Unable to link generated shader");
|
||||
return false;
|
||||
}
|
||||
@@ -194,21 +156,21 @@ bool GL4Shader::CompileProgram() {
|
||||
GLint binary_length = 0;
|
||||
glGetProgramiv(program_, GL_PROGRAM_BINARY_LENGTH, &binary_length);
|
||||
if (binary_length) {
|
||||
translated_binary_.resize(binary_length);
|
||||
host_binary_.resize(binary_length);
|
||||
GLenum binary_format;
|
||||
glGetProgramBinary(program_, binary_length, &binary_length, &binary_format,
|
||||
translated_binary_.data());
|
||||
host_binary_.data());
|
||||
|
||||
// If we are on nvidia, we can find the disassembly string.
|
||||
// I haven't been able to figure out from the format how to do this
|
||||
// without a search like this.
|
||||
const char* disasm_start = nullptr;
|
||||
size_t search_offset = 0;
|
||||
char* search_start = reinterpret_cast<char*>(translated_binary_.data());
|
||||
char* search_start = reinterpret_cast<char*>(host_binary_.data());
|
||||
while (true) {
|
||||
auto p = reinterpret_cast<char*>(
|
||||
memchr(translated_binary_.data() + search_offset, '!',
|
||||
translated_binary_.size() - search_offset));
|
||||
memchr(host_binary_.data() + search_offset, '!',
|
||||
host_binary_.size() - search_offset));
|
||||
if (!p) {
|
||||
break;
|
||||
}
|
||||
@@ -224,19 +186,6 @@ bool GL4Shader::CompileProgram() {
|
||||
} else {
|
||||
host_disassembly_ = std::string("Shader disassembly not available.");
|
||||
}
|
||||
|
||||
// Append to shader dump.
|
||||
if (!FLAGS_dump_shaders.empty()) {
|
||||
if (disasm_start) {
|
||||
FILE* f = fopen(file_name, "a");
|
||||
fprintf(f, "\n\n/*\n");
|
||||
fprintf(f, "%s", disasm_start);
|
||||
fprintf(f, "\n*/\n");
|
||||
fclose(f);
|
||||
} else {
|
||||
XELOGW("Got program binary but unable to find disassembly");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <string>
|
||||
|
||||
#include "xenia/gpu/shader.h"
|
||||
#include "xenia/gpu/shader_translator.h"
|
||||
#include "xenia/ui/gl/gl_context.h"
|
||||
|
||||
namespace xe {
|
||||
@@ -29,7 +28,7 @@ class GL4Shader : public Shader {
|
||||
GLuint program() const { return program_; }
|
||||
GLuint vao() const { return vao_; }
|
||||
|
||||
bool Prepare(ShaderTranslator* shader_translator);
|
||||
bool Prepare() override;
|
||||
|
||||
protected:
|
||||
bool PrepareVertexArrayObject();
|
||||
|
||||
Reference in New Issue
Block a user