diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc b/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc index 497479ac0..2f7dd1b93 100644 --- a/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc +++ b/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc @@ -69,6 +69,11 @@ void D3D11GraphicsDriver::SetShader( if (source) { xe_free(source); } + + // Prepare for use. + if (shader->Prepare()) { + XELOGGPU("D3D11: failed to prepare shader"); + } } void D3D11GraphicsDriver::DrawIndexed( diff --git a/src/xenia/gpu/d3d11/d3d11_shader.cc b/src/xenia/gpu/d3d11/d3d11_shader.cc index 73d0e6d40..da3592ade 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader.cc +++ b/src/xenia/gpu/d3d11/d3d11_shader.cc @@ -22,8 +22,56 @@ D3D11Shader::D3D11Shader( const uint8_t* src_ptr, size_t length, uint64_t hash) : Shader(type, src_ptr, length, hash) { - // TODO(benvanik): create shader/translate/etc. + device_ = device; + device_->AddRef(); } D3D11Shader::~D3D11Shader() { + device_->Release(); +} + + +D3D11VertexShader::D3D11VertexShader( + ID3D11Device* device, + const uint8_t* src_ptr, size_t length, + uint64_t hash) : + handle_(0), + D3D11Shader(device, XE_GPU_SHADER_TYPE_VERTEX, + src_ptr, length, hash) { +} + +D3D11VertexShader::~D3D11VertexShader() { + if (handle_) handle_->Release(); +} + +int D3D11VertexShader::Prepare() { + if (handle_) { + return 0; + } + + // TODO(benvanik): translate/etc. + return 0; +} + + +D3D11PixelShader::D3D11PixelShader( + ID3D11Device* device, + const uint8_t* src_ptr, size_t length, + uint64_t hash) : + handle_(0), + D3D11Shader(device, XE_GPU_SHADER_TYPE_PIXEL, + src_ptr, length, hash) { +} + +D3D11PixelShader::~D3D11PixelShader() { + if (handle_) handle_->Release(); +} + +int D3D11PixelShader::Prepare() { + if (handle_) { + return 0; + } + + // TODO(benvanik): translate/etc. + return 0; } diff --git a/src/xenia/gpu/d3d11/d3d11_shader.h b/src/xenia/gpu/d3d11/d3d11_shader.h index e2549fd77..c459de6a0 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader.h +++ b/src/xenia/gpu/d3d11/d3d11_shader.h @@ -24,12 +24,47 @@ namespace d3d11 { class D3D11Shader : public Shader { public: + virtual ~D3D11Shader(); + +protected: D3D11Shader( ID3D11Device* device, xenos::XE_GPU_SHADER_TYPE type, const uint8_t* src_ptr, size_t length, uint64_t hash); - virtual ~D3D11Shader(); + +protected: + ID3D11Device* device_; +}; + + +class D3D11VertexShader : public D3D11Shader { +public: + D3D11VertexShader( + ID3D11Device* device, + const uint8_t* src_ptr, size_t length, + uint64_t hash); + virtual ~D3D11VertexShader(); + + virtual int Prepare(); + +private: + ID3D11VertexShader* handle_; +}; + + +class D3D11PixelShader : public D3D11Shader { +public: + D3D11PixelShader( + ID3D11Device* device, + const uint8_t* src_ptr, size_t length, + uint64_t hash); + virtual ~D3D11PixelShader(); + + virtual int Prepare(); + +private: + ID3D11PixelShader* handle_; }; diff --git a/src/xenia/gpu/d3d11/d3d11_shader_cache.cc b/src/xenia/gpu/d3d11/d3d11_shader_cache.cc index cb95e5953..f3d907aad 100644 --- a/src/xenia/gpu/d3d11/d3d11_shader_cache.cc +++ b/src/xenia/gpu/d3d11/d3d11_shader_cache.cc @@ -15,6 +15,7 @@ using namespace xe; using namespace xe::gpu; using namespace xe::gpu::d3d11; +using namespace xe::gpu::xenos; D3D11ShaderCache::D3D11ShaderCache(ID3D11Device* device) { @@ -30,9 +31,15 @@ Shader* D3D11ShaderCache::CreateCore( xenos::XE_GPU_SHADER_TYPE type, const uint8_t* src_ptr, size_t length, uint32_t hash) { - return new D3D11Shader( - device_, - type, - src_ptr, length, - hash); + switch (type) { + case XE_GPU_SHADER_TYPE_VERTEX: + return new D3D11VertexShader( + device_, src_ptr, length, hash); + case XE_GPU_SHADER_TYPE_PIXEL: + return new D3D11PixelShader( + device_, src_ptr, length, hash); + default: + XEASSERTALWAYS(); + return NULL; + } } \ No newline at end of file diff --git a/src/xenia/gpu/nop/nop_graphics_driver.cc b/src/xenia/gpu/nop/nop_graphics_driver.cc index cb5df6da2..c0e7f86d9 100644 --- a/src/xenia/gpu/nop/nop_graphics_driver.cc +++ b/src/xenia/gpu/nop/nop_graphics_driver.cc @@ -64,6 +64,11 @@ void NopGraphicsDriver::SetShader( if (source) { xe_free(source); } + + // Prepare for use. + if (shader->Prepare()) { + XELOGGPU("NOP: failed to prepare shader"); + } } void NopGraphicsDriver::DrawIndexed( diff --git a/src/xenia/gpu/shader.cc b/src/xenia/gpu/shader.cc index 2f355cc35..bb745daa2 100644 --- a/src/xenia/gpu/shader.cc +++ b/src/xenia/gpu/shader.cc @@ -41,3 +41,7 @@ Shader::~Shader() { char* Shader::Disassemble() { return DisassembleShader(type_, dwords_, dword_count_); } + +int Shader::Prepare() { + return 0; +} diff --git a/src/xenia/gpu/shader.h b/src/xenia/gpu/shader.h index 108618759..5a6e1b985 100644 --- a/src/xenia/gpu/shader.h +++ b/src/xenia/gpu/shader.h @@ -37,6 +37,8 @@ public: // NOTE: xe_free() the returned string! char* Disassemble(); + virtual int Prepare(); + protected: xenos::XE_GPU_SHADER_TYPE type_; uint32_t* dwords_;