Vertex fetching.

This commit is contained in:
Ben Vanik 2013-10-12 02:29:01 -07:00
parent 04aad708c9
commit 8e01e2d945
18 changed files with 2762 additions and 54 deletions

View File

@ -10,6 +10,7 @@
#include <xenia/gpu/d3d11/d3d11_graphics_driver.h>
#include <xenia/gpu/gpu-private.h>
#include <xenia/gpu/d3d11/d3d11_shader.h>
#include <xenia/gpu/d3d11/d3d11_shader_cache.h>
@ -24,13 +25,35 @@ D3D11GraphicsDriver::D3D11GraphicsDriver(
GraphicsDriver(memory) {
device_ = device;
device_->AddRef();
device_->GetImmediateContext(&context_);
shader_cache_ = new D3D11ShaderCache(device_);
xe_zero_struct(&state_, sizeof(state_));
HRESULT hr;
D3D11_BUFFER_DESC buffer_desc;
xe_zero_struct(&buffer_desc, sizeof(buffer_desc));
buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
buffer_desc.ByteWidth = (512 * 4) * sizeof(float);
hr = device_->CreateBuffer(
&buffer_desc, NULL, &state_.constant_buffers.float_constants);
buffer_desc.ByteWidth = (8) * sizeof(int);
hr = device_->CreateBuffer(
&buffer_desc, NULL, &state_.constant_buffers.bool_constants);
buffer_desc.ByteWidth = (32) * sizeof(int);
hr = device_->CreateBuffer(
&buffer_desc, NULL, &state_.constant_buffers.loop_constants);
}
D3D11GraphicsDriver::~D3D11GraphicsDriver() {
XESAFERELEASE(state_.constant_buffers.float_constants);
XESAFERELEASE(state_.constant_buffers.bool_constants);
XESAFERELEASE(state_.constant_buffers.loop_constants);
delete shader_cache_;
device_->Release();
XESAFERELEASE(context_);
XESAFERELEASE(device_);
}
void D3D11GraphicsDriver::Initialize() {
@ -70,22 +93,264 @@ void D3D11GraphicsDriver::SetShader(
xe_free(source);
}
// Prepare for use.
if (shader->Prepare()) {
XELOGGPU("D3D11: failed to prepare shader");
// Stash for later.
switch (type) {
case XE_GPU_SHADER_TYPE_VERTEX:
state_.vertex_shader = (D3D11VertexShader*)shader;
break;
case XE_GPU_SHADER_TYPE_PIXEL:
state_.pixel_shader = (D3D11PixelShader*)shader;
break;
}
}
void D3D11GraphicsDriver::DrawIndexed(
void D3D11GraphicsDriver::DrawAutoIndexed(
XE_GPU_PRIMITIVE_TYPE prim_type,
uint32_t index_count) {
RegisterFile& rf = register_file_;
XELOGGPU("D3D11: draw indexed %d (%d indicies)",
prim_type, index_count);
// TODO(benvanik):
// program control
// context misc
// interpolator control
// shader constants / bools / integers
// fetch constants
// Misc state.
UpdateState();
// Build constant buffers.
UpdateConstantBuffers();
// Bind shaders.
BindShaders();
// Switch primitive topology.
// Some are unsupported on D3D11 and must be emulated.
D3D11_PRIMITIVE_TOPOLOGY primitive_topology;
switch (prim_type) {
default:
case XE_GPU_PRIMITIVE_TYPE_POINT_LIST:
primitive_topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
break;
case XE_GPU_PRIMITIVE_TYPE_LINE_LIST:
primitive_topology = D3D_PRIMITIVE_TOPOLOGY_LINELIST;
break;
case XE_GPU_PRIMITIVE_TYPE_LINE_STRIP:
primitive_topology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
break;
case XE_GPU_PRIMITIVE_TYPE_TRIANGLE_LIST:
primitive_topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
break;
case XE_GPU_PRIMITIVE_TYPE_TRIANGLE_STRIP:
primitive_topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
break;
case XE_GPU_PRIMITIVE_TYPE_TRIANGLE_FAN:
case XE_GPU_PRIMITIVE_TYPE_UNKNOWN_07:
case XE_GPU_PRIMITIVE_TYPE_RECTANGLE_LIST:
case XE_GPU_PRIMITIVE_TYPE_LINE_LOOP:
XELOGE("D3D11: unsupported primitive type %d", prim_type);
return;
}
context_->IASetPrimitiveTopology(primitive_topology);
// Setup all fetchers (vertices/textures).
PrepareFetchers();
// Setup index buffer.
PrepareIndexBuffer();
// Issue draw.
uint32_t start_index = rf.values[XE_GPU_REG_VGT_INDX_OFFSET].u32;
uint32_t base_vertex = 0;
//context_->DrawIndexed(index_count, start_index, base_vertex);
}
void D3D11GraphicsDriver::UpdateState() {
//context_->OMSetBlendState(blend_state, blend_factor, sample_mask);
//context_->OMSetDepthStencilState
//context_->RSSetScissorRects
//context_->RSSetState
//context_->RSSetViewports
}
void D3D11GraphicsDriver::UpdateConstantBuffers() {
RegisterFile& rf = register_file_;
D3D11_MAPPED_SUBRESOURCE res;
context_->Map(
state_.constant_buffers.float_constants, 0,
D3D11_MAP_WRITE_DISCARD, 0, &res);
memcpy(res.pData,
&rf.values[XE_GPU_REG_SHADER_CONSTANT_000_X],
(512 * 4) * sizeof(float));
context_->Unmap(state_.constant_buffers.float_constants, 0);
context_->Map(
state_.constant_buffers.loop_constants, 0,
D3D11_MAP_WRITE_DISCARD, 0, &res);
memcpy(res.pData,
&rf.values[XE_GPU_REG_SHADER_CONSTANT_LOOP_00],
(32) * sizeof(int));
context_->Unmap(state_.constant_buffers.loop_constants, 0);
context_->Map(
state_.constant_buffers.bool_constants, 0,
D3D11_MAP_WRITE_DISCARD, 0, &res);
memcpy(res.pData,
&rf.values[XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031],
(8) * sizeof(int));
context_->Unmap(state_.constant_buffers.bool_constants, 0);
}
void D3D11GraphicsDriver::BindShaders() {
RegisterFile& rf = register_file_;
xe_gpu_program_cntl_t program_cntl;
program_cntl.dword_0 = rf.values[XE_GPU_REG_SQ_PROGRAM_CNTL].u32;
// Vertex shader setup.
D3D11VertexShader* vs = state_.vertex_shader;
if (vs) {
if (!vs->is_prepared()) {
// Prepare for use.
if (vs->Prepare(&program_cntl)) {
XELOGGPU("D3D11: failed to prepare vertex shader");
state_.vertex_shader = NULL;
return;
}
}
// Bind.
context_->VSSetShader(vs->handle(), NULL, 0);
// Set constant buffers.
context_->VSSetConstantBuffers(
0,
sizeof(state_.constant_buffers) / sizeof(ID3D11Buffer*),
(ID3D11Buffer**)&state_.constant_buffers);
// Setup input layout (as encoded in vertex shader).
context_->IASetInputLayout(vs->input_layout());
//context_->VSSetSamplers
//context_->VSSetShaderResources
}
// Pixel shader setup.
D3D11PixelShader* ps = state_.pixel_shader;
if (ps) {
if (!ps->is_prepared()) {
// Prepare for use.
if (ps->Prepare(&program_cntl)) {
XELOGGPU("D3D11: failed to prepare pixel shader");
state_.pixel_shader = NULL;
return;
}
}
// Bind.
context_->PSSetShader(ps->handle(), NULL, 0);
// Set constant buffers.
context_->PSSetConstantBuffers(
0,
sizeof(state_.constant_buffers) / sizeof(ID3D11Buffer*),
(ID3D11Buffer**)&state_.constant_buffers);
//context_->PSSetSamplers
//context_->PSSetShaderResources
}
}
void D3D11GraphicsDriver::PrepareFetchers() {
RegisterFile& rf = register_file_;
for (int n = 0; n < 32; n++) {
int r = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 + n * 6;
xe_gpu_fetch_group_t* group = (xe_gpu_fetch_group_t*)&rf.values[r];
if (group->type_0 == 0x2) {
PrepareTextureFetcher(n, &group->texture_fetch);
} else {
// TODO(benvanik): verify register numbering.
if (group->type_0 == 0x3) {
PrepareVertexFetcher(n * 3 + 0, &group->vertex_fetch_0);
}
if (group->type_1 == 0x3) {
PrepareVertexFetcher(n * 3 + 1, &group->vertex_fetch_1);
}
if (group->type_2 == 0x3) {
PrepareVertexFetcher(n * 3 + 2, &group->vertex_fetch_2);
}
}
}
}
void D3D11GraphicsDriver::PrepareVertexFetcher(
int slot, xe_gpu_vertex_fetch_t* fetch) {
uint32_t address = (fetch->address << 2) + address_translation_;
uint32_t size_dwords = fetch->size;
ID3D11Buffer* buffer = 0;
D3D11_BUFFER_DESC buffer_desc;
xe_zero_struct(&buffer_desc, sizeof(buffer_desc));
buffer_desc.ByteWidth = size_dwords * 4;
buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
device_->CreateBuffer(&buffer_desc, NULL, &buffer);
D3D11_MAPPED_SUBRESOURCE res;
context_->Map(buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &res);
uint32_t* src = (uint32_t*)xe_memory_addr(memory_, address);
uint32_t* dest = (uint32_t*)res.pData;
for (uint32_t n = 0; n < size_dwords; n++) {
union {
uint32_t i;
float f;
} d = {XESWAP32(src[n])};
XELOGGPU("v%.3d %0.8X %g", n, d.i, d.f);
dest[n] = XESWAP32(src[n]);
}
context_->Unmap(buffer, 0);
// TODO(benvanik): fetch from VS.
/*uint32_t stride = 0;
uint32_t offset = 0;
context_->IASetVertexBuffers(slot, 1, &buffer, &stride, &offset);*/
buffer->Release();
}
void D3D11GraphicsDriver::PrepareTextureFetcher(
int slot, xe_gpu_texture_fetch_t* fetch) {
}
void D3D11GraphicsDriver::PrepareIndexBuffer() {
RegisterFile& rf = register_file_;
/*
ID3D11Buffer* buffer = 0;
D3D11_BUFFER_DESC buffer_desc;
xe_zero_struct(&buffer_desc, sizeof(buffer_desc));
buffer_desc.ByteWidth = size_dwords * 4;
buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
buffer_desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
device_->CreateBuffer(&buffer_desc, NULL, &buffer);
D3D11_MAPPED_SUBRESOURCE res;
context_->Map(buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &res);
uint32_t* src = (uint32_t*)xe_memory_addr(memory_, address);
uint32_t* dest = (uint32_t*)res.pData;
for (uint32_t n = 0; n < size_dwords; n++) {
union {
uint32_t i;
float f;
} d = {XESWAP32(src[n])};
XELOGGPU("v%.3d %0.8X %g", n, d.i, d.f);
dest[n] = XESWAP32(src[n]);
}
context_->Unmap(buffer, 0);
DXGI_FORMAT format;
format = DXGI_FORMAT_R16_UINT;
format = DXGI_FORMAT_R32_UINT;
context_->IASetIndexBuffer(buffer, format, 0);
buffer->Release();*/
}

View File

@ -23,7 +23,9 @@ namespace xe {
namespace gpu {
namespace d3d11 {
class D3D11PixelShader;
class D3D11ShaderCache;
class D3D11VertexShader;
class D3D11GraphicsDriver : public GraphicsDriver {
@ -40,14 +42,36 @@ public:
uint32_t address,
uint32_t start,
uint32_t length);
virtual void DrawIndexed(
virtual void DrawAutoIndexed(
xenos::XE_GPU_PRIMITIVE_TYPE prim_type,
uint32_t index_count);
private:
ID3D11Device* device_;
void UpdateState();
void UpdateConstantBuffers();
void BindShaders();
void PrepareFetchers();
void PrepareVertexFetcher(
int slot, xenos::xe_gpu_vertex_fetch_t* fetch);
void PrepareTextureFetcher(
int slot, xenos::xe_gpu_texture_fetch_t* fetch);
void PrepareIndexBuffer();
D3D11ShaderCache* shader_cache_;
private:
ID3D11Device* device_;
ID3D11DeviceContext* context_;
D3D11ShaderCache* shader_cache_;
struct {
D3D11VertexShader* vertex_shader;
D3D11PixelShader* pixel_shader;
struct {
ID3D11Buffer* float_constants;
ID3D11Buffer* bool_constants;
ID3D11Buffer* loop_constants;
} constant_buffers;
} state_;
};

View File

@ -30,8 +30,8 @@ D3D11GraphicsSystem::D3D11GraphicsSystem(const CreationParams* params) :
}
D3D11GraphicsSystem::~D3D11GraphicsSystem() {
if (device_) device_->Release();
if (dxgi_factory_) dxgi_factory_->Release();
XESAFERELEASE(device_);
XESAFERELEASE(dxgi_factory_);
delete window_;
}

View File

@ -27,7 +27,7 @@ D3D11Shader::D3D11Shader(
}
D3D11Shader::~D3D11Shader() {
device_->Release();
XESAFERELEASE(device_);
}
@ -35,21 +35,48 @@ D3D11VertexShader::D3D11VertexShader(
ID3D11Device* device,
const uint8_t* src_ptr, size_t length,
uint64_t hash) :
handle_(0),
handle_(0), input_layout_(0),
D3D11Shader(device, XE_GPU_SHADER_TYPE_VERTEX,
src_ptr, length, hash) {
}
D3D11VertexShader::~D3D11VertexShader() {
if (handle_) handle_->Release();
XESAFERELEASE(input_layout_);
XESAFERELEASE(handle_);
}
int D3D11VertexShader::Prepare() {
int D3D11VertexShader::Prepare(xe_gpu_program_cntl_t* program_cntl) {
if (handle_) {
return 0;
}
// TODO(benvanik): translate/etc.
const void* byte_code = NULL;
size_t byte_code_length = 0;
// Create shader.
HRESULT hr = device_->CreateVertexShader(
byte_code, byte_code_length,
NULL,
&handle_);
if (FAILED(hr)) {
XELOGE("D3D11: failed to create vertex shader");
return 1;
}
// Create input layout.
uint32_t element_count = 0;
D3D11_INPUT_ELEMENT_DESC* element_descs = 0;
hr = device_->CreateInputLayout(
element_descs,
element_count,
byte_code, byte_code_length,
&input_layout_);
if (FAILED(hr)) {
XELOGE("D3D11: failed to create vertex shader input layout");
return 1;
}
is_prepared_ = true;
return 0;
}
@ -64,14 +91,26 @@ D3D11PixelShader::D3D11PixelShader(
}
D3D11PixelShader::~D3D11PixelShader() {
if (handle_) handle_->Release();
XESAFERELEASE(handle_);
}
int D3D11PixelShader::Prepare() {
int D3D11PixelShader::Prepare(xe_gpu_program_cntl_t* program_cntl) {
if (handle_) {
return 0;
}
// TODO(benvanik): translate/etc.
const void* byte_code = NULL;
size_t byte_code_length = 0;
// Create shader.
HRESULT hr = device_->CreatePixelShader(
byte_code, byte_code_length,
NULL,
&handle_);
if (FAILED(hr)) {
XELOGE("D3D11: failed to create vertex shader");
return 1;
}
is_prepared_ = true;
return 0;
}

View File

@ -13,6 +13,7 @@
#include <xenia/core.h>
#include <xenia/gpu/shader.h>
#include <xenia/gpu/xenos/xenos.h>
#include <d3d11.h>
@ -46,10 +47,14 @@ public:
uint64_t hash);
virtual ~D3D11VertexShader();
virtual int Prepare();
ID3D11VertexShader* handle() const { return handle_; }
ID3D11InputLayout* input_layout() const { return input_layout_; }
int Prepare(xenos::xe_gpu_program_cntl_t* program_cntl);
private:
ID3D11VertexShader* handle_;
ID3D11InputLayout* input_layout_;
};
@ -61,7 +66,9 @@ public:
uint64_t hash);
virtual ~D3D11PixelShader();
virtual int Prepare();
ID3D11PixelShader* handle() const { return handle_; }
int Prepare(xenos::xe_gpu_program_cntl_t* program_cntl);
private:
ID3D11PixelShader* handle_;

View File

@ -30,7 +30,7 @@ D3D11ShaderCache::~D3D11ShaderCache() {
Shader* D3D11ShaderCache::CreateCore(
xenos::XE_GPU_SHADER_TYPE type,
const uint8_t* src_ptr, size_t length,
uint32_t hash) {
uint64_t hash) {
switch (type) {
case XE_GPU_SHADER_TYPE_VERTEX:
return new D3D11VertexShader(

View File

@ -31,7 +31,7 @@ protected:
virtual Shader* CreateCore(
xenos::XE_GPU_SHADER_TYPE type,
const uint8_t* src_ptr, size_t length,
uint32_t hash);
uint64_t hash);
protected:
ID3D11Device* device_;

View File

@ -82,14 +82,14 @@ D3D11Window::D3D11Window(
}
D3D11Window::~D3D11Window() {
if (render_target_view_) render_target_view_->Release();
if (context_) {
context_->ClearState();
context_->Release();
}
if (swap_chain_) swap_chain_->Release();
if (device_) device_->Release();
if (dxgi_factory_) dxgi_factory_->Release();
XESAFERELEASE(render_target_view_);
XESAFERELEASE(context_);
XESAFERELEASE(swap_chain_);
XESAFERELEASE(device_);
XESAFERELEASE(dxgi_factory_);
}
void D3D11Window::Swap() {

View File

@ -14,7 +14,8 @@ using namespace xe;
using namespace xe::gpu;
GraphicsDriver::GraphicsDriver(xe_memory_ref memory) {
GraphicsDriver::GraphicsDriver(xe_memory_ref memory) :
address_translation_(0) {
memory_ = xe_memory_retain(memory);
memset(&register_file_, 0, sizeof(register_file_));

View File

@ -25,6 +25,9 @@ public:
xe_memory_ref memory();
xenos::RegisterFile* register_file() { return &register_file_; };
void set_address_translation(uint32_t value) {
address_translation_ = value;
}
virtual void Initialize() = 0;
@ -35,7 +38,7 @@ public:
uint32_t address,
uint32_t start,
uint32_t length) = 0;
virtual void DrawIndexed(
virtual void DrawAutoIndexed(
xenos::XE_GPU_PRIMITIVE_TYPE prim_type,
uint32_t index_count) = 0;
@ -45,6 +48,7 @@ protected:
xe_memory_ref memory_;
xenos::RegisterFile register_file_;
uint32_t address_translation_;
};

View File

@ -64,14 +64,9 @@ void NopGraphicsDriver::SetShader(
if (source) {
xe_free(source);
}
// Prepare for use.
if (shader->Prepare()) {
XELOGGPU("NOP: failed to prepare shader");
}
}
void NopGraphicsDriver::DrawIndexed(
void NopGraphicsDriver::DrawAutoIndexed(
XE_GPU_PRIMITIVE_TYPE prim_type,
uint32_t index_count) {
XELOGGPU("NOP: draw indexed %d (%d indicies)",

View File

@ -39,7 +39,7 @@ public:
uint32_t address,
uint32_t start,
uint32_t length);
virtual void DrawIndexed(
virtual void DrawAutoIndexed(
xenos::XE_GPU_PRIMITIVE_TYPE prim_type,
uint32_t index_count);

View File

@ -98,6 +98,9 @@ void RingBufferWorker::ExecuteSegment(uint32_t ptr, uint32_t length) {
// Adjust pointer base.
ptr = (primary_buffer_ptr_ & ~0x1FFFFFFF) | (ptr & 0x1FFFFFFF);
// Tell the driver what to use for translation.
driver_->set_address_translation(primary_buffer_ptr_ & ~0x1FFFFFFF);
#define LOG_DATA(count) \
for (uint32_t __m = 0; __m < count; __m++) { \
XELOGGPU(" %.8X", XEGETUINT32BE(packet_base + 1 * 4 + __m * 4)); \
@ -200,6 +203,7 @@ void RingBufferWorker::ExecuteSegment(uint32_t ptr, uint32_t length) {
XELOGGPU("Packet(%.8X): PM4_INDIRECT_BUFFER %.8X (%dw)",
packet, list_ptr, list_length);
ExecuteSegment(list_ptr, list_length);
driver_->set_address_translation(primary_buffer_ptr_ & ~0x1FFFFFFF);
}
break;
@ -252,8 +256,9 @@ void RingBufferWorker::ExecuteSegment(uint32_t ptr, uint32_t length) {
uint32_t d1 = XEGETUINT32BE(packet_base + 2 * 4);
uint32_t index_count = d1 >> 16;
uint32_t prim_type = d1 & 0x3F;
// Not sure what the other bits mean - 'SrcSel=AutoIndex'?
driver_->DrawIndexed(
uint32_t src_sel = (d0 >> 6) & 0x3;
XEASSERT(src_sel == 0x2); // 'SrcSel=AutoIndex'
driver_->DrawAutoIndexed(
(XE_GPU_PRIMITIVE_TYPE)prim_type,
index_count);
}
@ -266,9 +271,9 @@ void RingBufferWorker::ExecuteSegment(uint32_t ptr, uint32_t length) {
uint32_t d0 = XEGETUINT32BE(packet_base + 1 * 4);
uint32_t index_count = d0 >> 16;
uint32_t prim_type = d0 & 0x3F;
// Not sure what the other bits mean - 'SrcSel=AutoIndex'?
// TODO(benvanik): verify this matches DRAW_INDX
driver_->DrawIndexed(
uint32_t src_sel = (d0 >> 6) & 0x3;
XEASSERT(src_sel == 0x2); // 'SrcSel=AutoIndex'
driver_->DrawAutoIndexed(
(XE_GPU_PRIMITIVE_TYPE)prim_type,
index_count);
}

View File

@ -41,7 +41,3 @@ Shader::~Shader() {
char* Shader::Disassemble() {
return DisassembleShader(type_, dwords_, dword_count_);
}
int Shader::Prepare() {
return 0;
}

View File

@ -29,6 +29,7 @@ public:
const uint32_t* dwords() const { return dwords_; }
size_t dword_count() const { return dword_count_; }
uint64_t hash() const { return hash_; }
bool is_prepared() const { return is_prepared_; }
// vfetch formats
// sampler formats
@ -37,13 +38,12 @@ public:
// NOTE: xe_free() the returned string!
char* Disassemble();
virtual int Prepare();
protected:
xenos::XE_GPU_SHADER_TYPE type_;
uint32_t* dwords_;
size_t dword_count_;
uint64_t hash_;
bool is_prepared_;
};

File diff suppressed because it is too large Load Diff

View File

@ -42,6 +42,90 @@ typedef enum {
XE_GPU_PRIMITIVE_TYPE_LINE_LOOP = 0x0C,
} XE_GPU_PRIMITIVE_TYPE;
// XE_GPU_REG_SQ_PROGRAM_CNTL
typedef union {
XEPACKEDSTRUCTANONYMOUS({
uint32_t vs_regs : 8;
uint32_t ps_regs : 8;
uint32_t vs_resource : 1;
uint32_t ps_resource : 1;
uint32_t param_gen : 1;
uint32_t unknown0 : 1;
uint32_t vs_export_count : 4;
uint32_t vs_export_mode : 3;
uint32_t ps_export_depth : 1;
uint32_t ps_export_count : 3;
uint32_t gen_index_vtx : 1;
});
XEPACKEDSTRUCTANONYMOUS({
uint32_t dword_0;
});
} xe_gpu_program_cntl_t;
// XE_GPU_REG_SHADER_CONSTANT_FETCH_*
XEPACKEDUNION(xe_gpu_vertex_fetch_t, {
XEPACKEDSTRUCTANONYMOUS({
uint32_t type : 2;
uint32_t address : 30;
uint32_t unk0 : 2;
uint32_t size : 24;
uint32_t unk1 : 6;
});
XEPACKEDSTRUCTANONYMOUS({
uint32_t dword_0;
uint32_t dword_1;
});
});
// XE_GPU_REG_SHADER_CONSTANT_FETCH_*
XEPACKEDUNION(xe_gpu_texture_fetch_t, {
XEPACKEDSTRUCTANONYMOUS({
uint32_t unk0;
uint32_t unk1;
uint32_t unk2;
uint32_t unk3;
uint32_t unk4;
uint32_t unk5;
});
XEPACKEDSTRUCTANONYMOUS({
uint32_t dword_0;
uint32_t dword_1;
uint32_t dword_2;
uint32_t dword_3;
uint32_t dword_4;
uint32_t dword_5;
});
});
// XE_GPU_REG_SHADER_CONSTANT_FETCH_*
XEPACKEDUNION(xe_gpu_fetch_group_t, {
xe_gpu_texture_fetch_t texture_fetch;
XEPACKEDSTRUCTANONYMOUS({
xe_gpu_vertex_fetch_t vertex_fetch_0;
xe_gpu_vertex_fetch_t vertex_fetch_1;
xe_gpu_vertex_fetch_t vertex_fetch_2;
});
XEPACKEDSTRUCTANONYMOUS({
uint32_t dword_0;
uint32_t dword_1;
uint32_t dword_2;
uint32_t dword_3;
uint32_t dword_4;
uint32_t dword_5;
});
XEPACKEDSTRUCTANONYMOUS({
uint32_t type_0 : 2;
uint32_t : 30;
uint32_t : 32;
uint32_t type_1 : 2;
uint32_t : 30;
uint32_t : 32;
uint32_t type_2 : 2;
uint32_t : 30;
uint32_t : 32;
});
});
} // namespace xenos
} // namespace gpu

View File

@ -119,6 +119,10 @@ typedef XECACHEALIGN volatile void xe_aligned_void_t;
#endif // GNUC
#endif // !MIN
#if XE_PLATFORM(WIN32)
#define XESAFERELEASE(p) if (p) { p->Release(); }
#endif // WIN32
#define XEBITMASK(a, b) (((unsigned) -1 >> (31 - (b))) & ~((1U << (a)) - 1))
#define XESELECTBITS(value, a, b) ((value & XEBITMASK(a, b)) >> a)