[D3D12] DXBC RDEF header

This commit is contained in:
Triang3l 2018-08-27 22:21:37 +03:00
parent 90a36e3818
commit ccb57373fe
2 changed files with 73 additions and 6 deletions

View File

@ -14,6 +14,7 @@
#include "third_party/dxbc/DXBCChecksum.h" #include "third_party/dxbc/DXBCChecksum.h"
#include "third_party/dxbc/d3d12TokenizedProgramFormat.hpp" #include "third_party/dxbc/d3d12TokenizedProgramFormat.hpp"
#include "xenia/base/assert.h"
#include "xenia/base/math.h" #include "xenia/base/math.h"
namespace xe { namespace xe {
@ -34,15 +35,31 @@ std::vector<uint8_t> DxbcShaderTranslator::CompleteTranslation() {
// Write the shader object header. // Write the shader object header.
shader_object_.push_back('CBXD'); shader_object_.push_back('CBXD');
// Reserve space for the checksum. // Checksum (set later).
for (uint32_t i = 0; i < 4; ++i) { for (uint32_t i = 0; i < 4; ++i) {
shader_object_.push_back(0); shader_object_.push_back(0);
} }
shader_object_.push_back(1); shader_object_.push_back(1);
// Reserve space for the size. // Size (set later).
shader_object_.push_back(0); shader_object_.push_back(0);
// 5 chunks - RDEF, ISGN, OSGN, SHEX, STAT. // 5 chunks - RDEF, ISGN, OSGN, SHEX, STAT.
shader_object_.push_back(5); shader_object_.push_back(5);
// Chunk offsets (set later).
for (uint32_t i = 0; i < shader_object_[7]; ++i) {
shader_object_.push_back(0);
}
uint32_t chunk_position_dwords;
// Write Resource DEFinitions.
chunk_position_dwords = uint32_t(shader_object_.size());
shader_object_[8] = chunk_position_dwords * sizeof(uint32_t);
shader_object_.push_back('FEDR');
shader_object_.push_back(0);
WriteResourceDefinitions();
shader_object_[chunk_position_dwords + 1] =
(uint32_t(shader_object_.size()) - chunk_position_dwords - 2) *
sizeof(uint32_t);
// Fill the remaining fields of the header and copy bytes out. // Fill the remaining fields of the header and copy bytes out.
uint32_t shader_object_size = uint32_t shader_object_size =
@ -64,13 +81,61 @@ uint32_t DxbcShaderTranslator::AppendString(std::vector<uint32_t>& dest,
const char* source) { const char* source) {
size_t size = std::strlen(source) + 1; size_t size = std::strlen(source) + 1;
size_t size_aligned = xe::align(size_aligned, sizeof(uint32_t)); size_t size_aligned = xe::align(size_aligned, sizeof(uint32_t));
size_t dest_pos = dest.size(); size_t dest_position = dest.size();
dest.resize(dest_pos + size_aligned / sizeof(uint32_t)); dest.resize(dest_position + size_aligned / sizeof(uint32_t));
std::memcpy(&dest[dest_pos], source, size); std::memcpy(&dest[dest_position], source, size);
std::memset(reinterpret_cast<uint8_t*>(&dest[dest_pos]) + size, 0xAB, std::memset(reinterpret_cast<uint8_t*>(&dest[dest_position]) + size, 0xAB,
size_aligned - size); size_aligned - size);
return uint32_t(size_aligned); return uint32_t(size_aligned);
} }
void DxbcShaderTranslator::WriteResourceDefinitions() {
uint32_t chunk_position_dwords = uint32_t(shader_object_.size());
// Write the header.
// Constant buffer count.
// b0 - Xenia system constants.
// b1 - bool and loop constants.
// b2 - fetch constants.
// b3-b10 - float constants.
shader_object_.push_back(4);
// Constant buffer offset (set later).
shader_object_.push_back(0);
// TODO(Triang3l): Bound resource count (CBV + other views) (set later).
shader_object_.push_back(4);
// TODO(Triang3l): Bound resource buffer offset (set later).
shader_object_.push_back(0);
if (is_vertex_shader()) {
// vs_5_1
shader_object_.push_back(0xFFFE0501u);
} else {
assert_true(is_pixel_shader());
// ps_5_1
shader_object_.push_back(0xFFFF0501u);
}
// Compiler flags - default for SM 5.1 (no preshader, prefer flow control).
shader_object_.push_back(0x500);
// Generator offset (directly after the RDEF header in our case).
shader_object_.push_back(60);
// RD11, but with nibbles inverted (unlike in SM 5.0).
shader_object_.push_back(0x25441313);
// Unknown fields.
shader_object_.push_back(60);
shader_object_.push_back(24);
// Was 32 in SM 5.0.
shader_object_.push_back(40);
shader_object_.push_back(40);
shader_object_.push_back(36);
shader_object_.push_back(12);
shader_object_.push_back(0);
// Generator name.
AppendString(shader_object_, "Xenia");
// Constant buffers.
uint32_t cbuffer_position_dwords = uint32_t(shader_object_.size());
shader_object_[chunk_position_dwords + 1] =
cbuffer_position_dwords * sizeof(uint32_t);
}
} // namespace gpu } // namespace gpu
} // namespace xe } // namespace xe

View File

@ -32,6 +32,8 @@ class DxbcShaderTranslator : public ShaderTranslator {
// Appends a string to a DWORD stream, returns the DWORD-aligned length. // Appends a string to a DWORD stream, returns the DWORD-aligned length.
static uint32_t AppendString(std::vector<uint32_t>& dest, const char* source); static uint32_t AppendString(std::vector<uint32_t>& dest, const char* source);
void WriteResourceDefinitions();
// Executable instructions - generated during translation. // Executable instructions - generated during translation.
std::vector<uint32_t> shader_code_; std::vector<uint32_t> shader_code_;
// Complete shader object, with all the needed chunks and dcl_ instructions - // Complete shader object, with all the needed chunks and dcl_ instructions -