Vertex fetching.
This commit is contained in:
parent
04aad708c9
commit
8e01e2d945
|
@ -10,6 +10,7 @@
|
||||||
#include <xenia/gpu/d3d11/d3d11_graphics_driver.h>
|
#include <xenia/gpu/d3d11/d3d11_graphics_driver.h>
|
||||||
|
|
||||||
#include <xenia/gpu/gpu-private.h>
|
#include <xenia/gpu/gpu-private.h>
|
||||||
|
#include <xenia/gpu/d3d11/d3d11_shader.h>
|
||||||
#include <xenia/gpu/d3d11/d3d11_shader_cache.h>
|
#include <xenia/gpu/d3d11/d3d11_shader_cache.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,13 +25,35 @@ D3D11GraphicsDriver::D3D11GraphicsDriver(
|
||||||
GraphicsDriver(memory) {
|
GraphicsDriver(memory) {
|
||||||
device_ = device;
|
device_ = device;
|
||||||
device_->AddRef();
|
device_->AddRef();
|
||||||
|
device_->GetImmediateContext(&context_);
|
||||||
shader_cache_ = new D3D11ShaderCache(device_);
|
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() {
|
D3D11GraphicsDriver::~D3D11GraphicsDriver() {
|
||||||
|
XESAFERELEASE(state_.constant_buffers.float_constants);
|
||||||
|
XESAFERELEASE(state_.constant_buffers.bool_constants);
|
||||||
|
XESAFERELEASE(state_.constant_buffers.loop_constants);
|
||||||
delete shader_cache_;
|
delete shader_cache_;
|
||||||
device_->Release();
|
XESAFERELEASE(context_);
|
||||||
|
XESAFERELEASE(device_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11GraphicsDriver::Initialize() {
|
void D3D11GraphicsDriver::Initialize() {
|
||||||
|
@ -70,22 +93,264 @@ void D3D11GraphicsDriver::SetShader(
|
||||||
xe_free(source);
|
xe_free(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare for use.
|
// Stash for later.
|
||||||
if (shader->Prepare()) {
|
switch (type) {
|
||||||
XELOGGPU("D3D11: failed to prepare shader");
|
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,
|
XE_GPU_PRIMITIVE_TYPE prim_type,
|
||||||
uint32_t index_count) {
|
uint32_t index_count) {
|
||||||
|
RegisterFile& rf = register_file_;
|
||||||
|
|
||||||
XELOGGPU("D3D11: draw indexed %d (%d indicies)",
|
XELOGGPU("D3D11: draw indexed %d (%d indicies)",
|
||||||
prim_type, index_count);
|
prim_type, index_count);
|
||||||
|
|
||||||
// TODO(benvanik):
|
// Misc state.
|
||||||
// program control
|
UpdateState();
|
||||||
// context misc
|
|
||||||
// interpolator control
|
// Build constant buffers.
|
||||||
// shader constants / bools / integers
|
UpdateConstantBuffers();
|
||||||
// fetch constants
|
|
||||||
|
// 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();*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,9 @@ namespace xe {
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
namespace d3d11 {
|
namespace d3d11 {
|
||||||
|
|
||||||
|
class D3D11PixelShader;
|
||||||
class D3D11ShaderCache;
|
class D3D11ShaderCache;
|
||||||
|
class D3D11VertexShader;
|
||||||
|
|
||||||
|
|
||||||
class D3D11GraphicsDriver : public GraphicsDriver {
|
class D3D11GraphicsDriver : public GraphicsDriver {
|
||||||
|
@ -40,14 +42,36 @@ public:
|
||||||
uint32_t address,
|
uint32_t address,
|
||||||
uint32_t start,
|
uint32_t start,
|
||||||
uint32_t length);
|
uint32_t length);
|
||||||
virtual void DrawIndexed(
|
virtual void DrawAutoIndexed(
|
||||||
xenos::XE_GPU_PRIMITIVE_TYPE prim_type,
|
xenos::XE_GPU_PRIMITIVE_TYPE prim_type,
|
||||||
uint32_t index_count);
|
uint32_t index_count);
|
||||||
|
|
||||||
private:
|
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();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ID3D11Device* device_;
|
||||||
|
ID3D11DeviceContext* context_;
|
||||||
D3D11ShaderCache* shader_cache_;
|
D3D11ShaderCache* shader_cache_;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
D3D11VertexShader* vertex_shader;
|
||||||
|
D3D11PixelShader* pixel_shader;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
ID3D11Buffer* float_constants;
|
||||||
|
ID3D11Buffer* bool_constants;
|
||||||
|
ID3D11Buffer* loop_constants;
|
||||||
|
} constant_buffers;
|
||||||
|
} state_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,8 +30,8 @@ D3D11GraphicsSystem::D3D11GraphicsSystem(const CreationParams* params) :
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D11GraphicsSystem::~D3D11GraphicsSystem() {
|
D3D11GraphicsSystem::~D3D11GraphicsSystem() {
|
||||||
if (device_) device_->Release();
|
XESAFERELEASE(device_);
|
||||||
if (dxgi_factory_) dxgi_factory_->Release();
|
XESAFERELEASE(dxgi_factory_);
|
||||||
delete window_;
|
delete window_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ D3D11Shader::D3D11Shader(
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D11Shader::~D3D11Shader() {
|
D3D11Shader::~D3D11Shader() {
|
||||||
device_->Release();
|
XESAFERELEASE(device_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,21 +35,48 @@ D3D11VertexShader::D3D11VertexShader(
|
||||||
ID3D11Device* device,
|
ID3D11Device* device,
|
||||||
const uint8_t* src_ptr, size_t length,
|
const uint8_t* src_ptr, size_t length,
|
||||||
uint64_t hash) :
|
uint64_t hash) :
|
||||||
handle_(0),
|
handle_(0), input_layout_(0),
|
||||||
D3D11Shader(device, XE_GPU_SHADER_TYPE_VERTEX,
|
D3D11Shader(device, XE_GPU_SHADER_TYPE_VERTEX,
|
||||||
src_ptr, length, hash) {
|
src_ptr, length, hash) {
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D11VertexShader::~D3D11VertexShader() {
|
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_) {
|
if (handle_) {
|
||||||
return 0;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,14 +91,26 @@ D3D11PixelShader::D3D11PixelShader(
|
||||||
}
|
}
|
||||||
|
|
||||||
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_) {
|
if (handle_) {
|
||||||
return 0;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <xenia/core.h>
|
#include <xenia/core.h>
|
||||||
|
|
||||||
#include <xenia/gpu/shader.h>
|
#include <xenia/gpu/shader.h>
|
||||||
|
#include <xenia/gpu/xenos/xenos.h>
|
||||||
|
|
||||||
#include <d3d11.h>
|
#include <d3d11.h>
|
||||||
|
|
||||||
|
@ -46,10 +47,14 @@ public:
|
||||||
uint64_t hash);
|
uint64_t hash);
|
||||||
virtual ~D3D11VertexShader();
|
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:
|
private:
|
||||||
ID3D11VertexShader* handle_;
|
ID3D11VertexShader* handle_;
|
||||||
|
ID3D11InputLayout* input_layout_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,7 +66,9 @@ public:
|
||||||
uint64_t hash);
|
uint64_t hash);
|
||||||
virtual ~D3D11PixelShader();
|
virtual ~D3D11PixelShader();
|
||||||
|
|
||||||
virtual int Prepare();
|
ID3D11PixelShader* handle() const { return handle_; }
|
||||||
|
|
||||||
|
int Prepare(xenos::xe_gpu_program_cntl_t* program_cntl);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ID3D11PixelShader* handle_;
|
ID3D11PixelShader* handle_;
|
||||||
|
|
|
@ -30,7 +30,7 @@ D3D11ShaderCache::~D3D11ShaderCache() {
|
||||||
Shader* D3D11ShaderCache::CreateCore(
|
Shader* D3D11ShaderCache::CreateCore(
|
||||||
xenos::XE_GPU_SHADER_TYPE type,
|
xenos::XE_GPU_SHADER_TYPE type,
|
||||||
const uint8_t* src_ptr, size_t length,
|
const uint8_t* src_ptr, size_t length,
|
||||||
uint32_t hash) {
|
uint64_t hash) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case XE_GPU_SHADER_TYPE_VERTEX:
|
case XE_GPU_SHADER_TYPE_VERTEX:
|
||||||
return new D3D11VertexShader(
|
return new D3D11VertexShader(
|
||||||
|
|
|
@ -31,7 +31,7 @@ protected:
|
||||||
virtual Shader* CreateCore(
|
virtual Shader* CreateCore(
|
||||||
xenos::XE_GPU_SHADER_TYPE type,
|
xenos::XE_GPU_SHADER_TYPE type,
|
||||||
const uint8_t* src_ptr, size_t length,
|
const uint8_t* src_ptr, size_t length,
|
||||||
uint32_t hash);
|
uint64_t hash);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ID3D11Device* device_;
|
ID3D11Device* device_;
|
||||||
|
|
|
@ -82,14 +82,14 @@ D3D11Window::D3D11Window(
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D11Window::~D3D11Window() {
|
D3D11Window::~D3D11Window() {
|
||||||
if (render_target_view_) render_target_view_->Release();
|
|
||||||
if (context_) {
|
if (context_) {
|
||||||
context_->ClearState();
|
context_->ClearState();
|
||||||
context_->Release();
|
|
||||||
}
|
}
|
||||||
if (swap_chain_) swap_chain_->Release();
|
XESAFERELEASE(render_target_view_);
|
||||||
if (device_) device_->Release();
|
XESAFERELEASE(context_);
|
||||||
if (dxgi_factory_) dxgi_factory_->Release();
|
XESAFERELEASE(swap_chain_);
|
||||||
|
XESAFERELEASE(device_);
|
||||||
|
XESAFERELEASE(dxgi_factory_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11Window::Swap() {
|
void D3D11Window::Swap() {
|
||||||
|
|
|
@ -14,7 +14,8 @@ using namespace xe;
|
||||||
using namespace xe::gpu;
|
using namespace xe::gpu;
|
||||||
|
|
||||||
|
|
||||||
GraphicsDriver::GraphicsDriver(xe_memory_ref memory) {
|
GraphicsDriver::GraphicsDriver(xe_memory_ref memory) :
|
||||||
|
address_translation_(0) {
|
||||||
memory_ = xe_memory_retain(memory);
|
memory_ = xe_memory_retain(memory);
|
||||||
|
|
||||||
memset(®ister_file_, 0, sizeof(register_file_));
|
memset(®ister_file_, 0, sizeof(register_file_));
|
||||||
|
|
|
@ -25,6 +25,9 @@ public:
|
||||||
|
|
||||||
xe_memory_ref memory();
|
xe_memory_ref memory();
|
||||||
xenos::RegisterFile* register_file() { return ®ister_file_; };
|
xenos::RegisterFile* register_file() { return ®ister_file_; };
|
||||||
|
void set_address_translation(uint32_t value) {
|
||||||
|
address_translation_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void Initialize() = 0;
|
virtual void Initialize() = 0;
|
||||||
|
|
||||||
|
@ -35,7 +38,7 @@ public:
|
||||||
uint32_t address,
|
uint32_t address,
|
||||||
uint32_t start,
|
uint32_t start,
|
||||||
uint32_t length) = 0;
|
uint32_t length) = 0;
|
||||||
virtual void DrawIndexed(
|
virtual void DrawAutoIndexed(
|
||||||
xenos::XE_GPU_PRIMITIVE_TYPE prim_type,
|
xenos::XE_GPU_PRIMITIVE_TYPE prim_type,
|
||||||
uint32_t index_count) = 0;
|
uint32_t index_count) = 0;
|
||||||
|
|
||||||
|
@ -45,6 +48,7 @@ protected:
|
||||||
xe_memory_ref memory_;
|
xe_memory_ref memory_;
|
||||||
|
|
||||||
xenos::RegisterFile register_file_;
|
xenos::RegisterFile register_file_;
|
||||||
|
uint32_t address_translation_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,14 +64,9 @@ void NopGraphicsDriver::SetShader(
|
||||||
if (source) {
|
if (source) {
|
||||||
xe_free(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,
|
XE_GPU_PRIMITIVE_TYPE prim_type,
|
||||||
uint32_t index_count) {
|
uint32_t index_count) {
|
||||||
XELOGGPU("NOP: draw indexed %d (%d indicies)",
|
XELOGGPU("NOP: draw indexed %d (%d indicies)",
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
uint32_t address,
|
uint32_t address,
|
||||||
uint32_t start,
|
uint32_t start,
|
||||||
uint32_t length);
|
uint32_t length);
|
||||||
virtual void DrawIndexed(
|
virtual void DrawAutoIndexed(
|
||||||
xenos::XE_GPU_PRIMITIVE_TYPE prim_type,
|
xenos::XE_GPU_PRIMITIVE_TYPE prim_type,
|
||||||
uint32_t index_count);
|
uint32_t index_count);
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,9 @@ void RingBufferWorker::ExecuteSegment(uint32_t ptr, uint32_t length) {
|
||||||
// Adjust pointer base.
|
// Adjust pointer base.
|
||||||
ptr = (primary_buffer_ptr_ & ~0x1FFFFFFF) | (ptr & 0x1FFFFFFF);
|
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) \
|
#define LOG_DATA(count) \
|
||||||
for (uint32_t __m = 0; __m < count; __m++) { \
|
for (uint32_t __m = 0; __m < count; __m++) { \
|
||||||
XELOGGPU(" %.8X", XEGETUINT32BE(packet_base + 1 * 4 + __m * 4)); \
|
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)",
|
XELOGGPU("Packet(%.8X): PM4_INDIRECT_BUFFER %.8X (%dw)",
|
||||||
packet, list_ptr, list_length);
|
packet, list_ptr, list_length);
|
||||||
ExecuteSegment(list_ptr, list_length);
|
ExecuteSegment(list_ptr, list_length);
|
||||||
|
driver_->set_address_translation(primary_buffer_ptr_ & ~0x1FFFFFFF);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -252,8 +256,9 @@ void RingBufferWorker::ExecuteSegment(uint32_t ptr, uint32_t length) {
|
||||||
uint32_t d1 = XEGETUINT32BE(packet_base + 2 * 4);
|
uint32_t d1 = XEGETUINT32BE(packet_base + 2 * 4);
|
||||||
uint32_t index_count = d1 >> 16;
|
uint32_t index_count = d1 >> 16;
|
||||||
uint32_t prim_type = d1 & 0x3F;
|
uint32_t prim_type = d1 & 0x3F;
|
||||||
// Not sure what the other bits mean - 'SrcSel=AutoIndex'?
|
uint32_t src_sel = (d0 >> 6) & 0x3;
|
||||||
driver_->DrawIndexed(
|
XEASSERT(src_sel == 0x2); // 'SrcSel=AutoIndex'
|
||||||
|
driver_->DrawAutoIndexed(
|
||||||
(XE_GPU_PRIMITIVE_TYPE)prim_type,
|
(XE_GPU_PRIMITIVE_TYPE)prim_type,
|
||||||
index_count);
|
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 d0 = XEGETUINT32BE(packet_base + 1 * 4);
|
||||||
uint32_t index_count = d0 >> 16;
|
uint32_t index_count = d0 >> 16;
|
||||||
uint32_t prim_type = d0 & 0x3F;
|
uint32_t prim_type = d0 & 0x3F;
|
||||||
// Not sure what the other bits mean - 'SrcSel=AutoIndex'?
|
uint32_t src_sel = (d0 >> 6) & 0x3;
|
||||||
// TODO(benvanik): verify this matches DRAW_INDX
|
XEASSERT(src_sel == 0x2); // 'SrcSel=AutoIndex'
|
||||||
driver_->DrawIndexed(
|
driver_->DrawAutoIndexed(
|
||||||
(XE_GPU_PRIMITIVE_TYPE)prim_type,
|
(XE_GPU_PRIMITIVE_TYPE)prim_type,
|
||||||
index_count);
|
index_count);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,3 @@ Shader::~Shader() {
|
||||||
char* Shader::Disassemble() {
|
char* Shader::Disassemble() {
|
||||||
return DisassembleShader(type_, dwords_, dword_count_);
|
return DisassembleShader(type_, dwords_, dword_count_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Shader::Prepare() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ public:
|
||||||
const uint32_t* dwords() const { return dwords_; }
|
const uint32_t* dwords() const { return dwords_; }
|
||||||
size_t dword_count() const { return dword_count_; }
|
size_t dword_count() const { return dword_count_; }
|
||||||
uint64_t hash() const { return hash_; }
|
uint64_t hash() const { return hash_; }
|
||||||
|
bool is_prepared() const { return is_prepared_; }
|
||||||
|
|
||||||
// vfetch formats
|
// vfetch formats
|
||||||
// sampler formats
|
// sampler formats
|
||||||
|
@ -37,13 +38,12 @@ public:
|
||||||
// NOTE: xe_free() the returned string!
|
// NOTE: xe_free() the returned string!
|
||||||
char* Disassemble();
|
char* Disassemble();
|
||||||
|
|
||||||
virtual int Prepare();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
xenos::XE_GPU_SHADER_TYPE type_;
|
xenos::XE_GPU_SHADER_TYPE type_;
|
||||||
uint32_t* dwords_;
|
uint32_t* dwords_;
|
||||||
size_t dword_count_;
|
size_t dword_count_;
|
||||||
uint64_t hash_;
|
uint64_t hash_;
|
||||||
|
bool is_prepared_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -42,6 +42,90 @@ typedef enum {
|
||||||
XE_GPU_PRIMITIVE_TYPE_LINE_LOOP = 0x0C,
|
XE_GPU_PRIMITIVE_TYPE_LINE_LOOP = 0x0C,
|
||||||
} XE_GPU_PRIMITIVE_TYPE;
|
} 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 xenos
|
||||||
} // namespace gpu
|
} // namespace gpu
|
||||||
|
|
|
@ -119,6 +119,10 @@ typedef XECACHEALIGN volatile void xe_aligned_void_t;
|
||||||
#endif // GNUC
|
#endif // GNUC
|
||||||
#endif // !MIN
|
#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 XEBITMASK(a, b) (((unsigned) -1 >> (31 - (b))) & ~((1U << (a)) - 1))
|
||||||
#define XESELECTBITS(value, a, b) ((value & XEBITMASK(a, b)) >> a)
|
#define XESELECTBITS(value, a, b) ((value & XEBITMASK(a, b)) >> a)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue