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/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();*/
|
||||
}
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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_;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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(®ister_file_, 0, sizeof(register_file_));
|
||||
|
|
|
@ -25,6 +25,9 @@ public:
|
|||
|
||||
xe_memory_ref memory();
|
||||
xenos::RegisterFile* register_file() { return ®ister_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_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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)",
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,3 @@ Shader::~Shader() {
|
|||
char* Shader::Disassemble() {
|
||||
return DisassembleShader(type_, dwords_, dword_count_);
|
||||
}
|
||||
|
||||
int Shader::Prepare() {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue