Initial refactoring of gpu/.
Runs too fast - now there are ringbuffer wrapping issues.
This commit is contained in:
@@ -1,150 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/gpu/d3d11/d3d11_buffer.h>
|
||||
|
||||
#include <xenia/gpu/gpu-private.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_buffer_cache.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::gpu;
|
||||
using namespace xe::gpu::d3d11;
|
||||
using namespace xe::gpu::xenos;
|
||||
|
||||
|
||||
D3D11IndexBuffer::D3D11IndexBuffer(
|
||||
D3D11BufferCache* buffer_cache,
|
||||
const IndexBufferInfo& info,
|
||||
const uint8_t* src_ptr, size_t length)
|
||||
: IndexBuffer(info, src_ptr, length),
|
||||
buffer_cache_(buffer_cache),
|
||||
handle_(nullptr) {
|
||||
}
|
||||
|
||||
D3D11IndexBuffer::~D3D11IndexBuffer() {
|
||||
XESAFERELEASE(handle_);
|
||||
}
|
||||
|
||||
bool D3D11IndexBuffer::FetchNew(uint64_t hash) {
|
||||
hash_ = hash;
|
||||
|
||||
D3D11_BUFFER_DESC buffer_desc;
|
||||
xe_zero_struct(&buffer_desc, sizeof(buffer_desc));
|
||||
buffer_desc.ByteWidth = info_.index_size;
|
||||
buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
buffer_desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
HRESULT hr = buffer_cache_->device()->CreateBuffer(&buffer_desc, NULL, &handle_);
|
||||
if (FAILED(hr)) {
|
||||
XELOGW("D3D11: failed to create index buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
return FetchDirty(hash);
|
||||
}
|
||||
|
||||
bool D3D11IndexBuffer::FetchDirty(uint64_t hash) {
|
||||
hash_ = hash;
|
||||
|
||||
// All that's done so far:
|
||||
XEASSERT(info_.endianness == 0x2);
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE res;
|
||||
HRESULT hr = buffer_cache_->context()->Map(
|
||||
handle_, 0, D3D11_MAP_WRITE_DISCARD, 0, &res);
|
||||
if (FAILED(hr)) {
|
||||
XELOGE("D3D11: unable to map index buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (info_.index_32bit) {
|
||||
const uint32_t* src = reinterpret_cast<const uint32_t*>(src_);
|
||||
uint32_t* dest = reinterpret_cast<uint32_t*>(res.pData);
|
||||
for (uint32_t n = 0; n < info_.index_count; n++) {
|
||||
uint32_t d = { XESWAP32(src[n]) };
|
||||
dest[n] = d;
|
||||
}
|
||||
} else {
|
||||
const uint16_t* src = reinterpret_cast<const uint16_t*>(src_);
|
||||
uint16_t* dest = reinterpret_cast<uint16_t*>(res.pData);
|
||||
for (uint32_t n = 0; n < info_.index_count; n++) {
|
||||
uint16_t d = XESWAP16(src[n]);
|
||||
dest[n] = d;
|
||||
}
|
||||
}
|
||||
buffer_cache_->context()->Unmap(handle_, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
D3D11VertexBuffer::D3D11VertexBuffer(
|
||||
D3D11BufferCache* buffer_cache,
|
||||
const VertexBufferInfo& info,
|
||||
const uint8_t* src_ptr, size_t length)
|
||||
: VertexBuffer(info, src_ptr, length),
|
||||
buffer_cache_(buffer_cache),
|
||||
handle_(nullptr) {
|
||||
}
|
||||
|
||||
D3D11VertexBuffer::~D3D11VertexBuffer() {
|
||||
XESAFERELEASE(handle_);
|
||||
}
|
||||
|
||||
bool D3D11VertexBuffer::FetchNew(uint64_t hash) {
|
||||
hash_ = hash;
|
||||
|
||||
D3D11_BUFFER_DESC buffer_desc;
|
||||
xe_zero_struct(&buffer_desc, sizeof(buffer_desc));
|
||||
buffer_desc.ByteWidth = static_cast<UINT>(length_);
|
||||
buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
HRESULT hr = buffer_cache_->device()->CreateBuffer(&buffer_desc, NULL, &handle_);
|
||||
if (FAILED(hr)) {
|
||||
XELOGW("D3D11: failed to create index buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
return FetchDirty(hash);
|
||||
}
|
||||
|
||||
bool D3D11VertexBuffer::FetchDirty(uint64_t hash) {
|
||||
hash_ = hash;
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE res;
|
||||
HRESULT hr = buffer_cache_->context()->Map(
|
||||
handle_, 0, D3D11_MAP_WRITE_DISCARD, 0, &res);
|
||||
if (FAILED(hr)) {
|
||||
XELOGE("D3D11: unable to map vertex buffer");
|
||||
return false;
|
||||
}
|
||||
uint8_t* dest = reinterpret_cast<uint8_t*>(res.pData);
|
||||
|
||||
// TODO(benvanik): rewrite to be faster/special case common/etc
|
||||
uint32_t stride = info_.layout.stride_words;
|
||||
size_t count = (length_ / 4) / stride;
|
||||
for (size_t n = 0; n < info_.layout.element_count; n++) {
|
||||
const auto& el = info_.layout.elements[n];
|
||||
const uint32_t* src_ptr = (const uint32_t*)(src_ + el.offset_words * 4);
|
||||
uint32_t* dest_ptr = (uint32_t*)(dest + el.offset_words * 4);
|
||||
uint32_t o = 0;
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
for (uint32_t j = 0; j < el.size_words; j++) {
|
||||
dest_ptr[o + j] = XESWAP32(src_ptr[o + j]);
|
||||
}
|
||||
o += stride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
buffer_cache_->context()->Unmap(handle_, 0);
|
||||
return true;
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_GPU_D3D11_D3D11_BUFFER_H_
|
||||
#define XENIA_GPU_D3D11_D3D11_BUFFER_H_
|
||||
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/gpu/buffer.h>
|
||||
#include <xenia/gpu/xenos/xenos.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d11 {
|
||||
|
||||
class D3D11BufferCache;
|
||||
|
||||
|
||||
class D3D11IndexBuffer : public IndexBuffer {
|
||||
public:
|
||||
D3D11IndexBuffer(D3D11BufferCache* buffer_cache,
|
||||
const IndexBufferInfo& info,
|
||||
const uint8_t* src_ptr, size_t length);
|
||||
virtual ~D3D11IndexBuffer();
|
||||
|
||||
ID3D11Buffer* handle() const { return handle_; }
|
||||
|
||||
bool FetchNew(uint64_t hash) override;
|
||||
bool FetchDirty(uint64_t hash) override;
|
||||
|
||||
private:
|
||||
D3D11BufferCache* buffer_cache_;
|
||||
ID3D11Buffer* handle_;
|
||||
};
|
||||
|
||||
|
||||
class D3D11VertexBuffer : public VertexBuffer {
|
||||
public:
|
||||
D3D11VertexBuffer(D3D11BufferCache* buffer_cache,
|
||||
const VertexBufferInfo& info,
|
||||
const uint8_t* src_ptr, size_t length);
|
||||
virtual ~D3D11VertexBuffer();
|
||||
|
||||
ID3D11Buffer* handle() const { return handle_; }
|
||||
|
||||
bool FetchNew(uint64_t hash) override;
|
||||
bool FetchDirty(uint64_t hash) override;
|
||||
|
||||
private:
|
||||
D3D11BufferCache* buffer_cache_;
|
||||
ID3D11Buffer* handle_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace d3d11
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_GPU_D3D11_D3D11_BUFFER_H_
|
||||
@@ -1,44 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/gpu/d3d11/d3d11_buffer_cache.h>
|
||||
|
||||
#include <xenia/gpu/gpu-private.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_buffer.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::gpu;
|
||||
using namespace xe::gpu::d3d11;
|
||||
using namespace xe::gpu::xenos;
|
||||
|
||||
|
||||
D3D11BufferCache::D3D11BufferCache(ID3D11DeviceContext* context,
|
||||
ID3D11Device* device)
|
||||
: context_(context), device_(device) {
|
||||
context->AddRef();
|
||||
device_->AddRef();
|
||||
}
|
||||
|
||||
D3D11BufferCache::~D3D11BufferCache() {
|
||||
XESAFERELEASE(device_);
|
||||
XESAFERELEASE(context_);
|
||||
}
|
||||
|
||||
IndexBuffer* D3D11BufferCache::CreateIndexBuffer(
|
||||
const IndexBufferInfo& info,
|
||||
const uint8_t* src_ptr, size_t length) {
|
||||
return new D3D11IndexBuffer(this, info, src_ptr, length);
|
||||
}
|
||||
|
||||
VertexBuffer* D3D11BufferCache::CreateVertexBuffer(
|
||||
const VertexBufferInfo& info,
|
||||
const uint8_t* src_ptr, size_t length) {
|
||||
return new D3D11VertexBuffer(this, info, src_ptr, length);
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_GPU_D3D11_D3D11_BUFFER_CACHE_H_
|
||||
#define XENIA_GPU_D3D11_D3D11_BUFFER_CACHE_H_
|
||||
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/gpu/buffer_cache.h>
|
||||
#include <xenia/gpu/xenos/xenos.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d11 {
|
||||
|
||||
|
||||
class D3D11BufferCache : public BufferCache {
|
||||
public:
|
||||
D3D11BufferCache(ID3D11DeviceContext* context, ID3D11Device* device);
|
||||
virtual ~D3D11BufferCache();
|
||||
|
||||
ID3D11DeviceContext* context() const { return context_; }
|
||||
ID3D11Device* device() const { return device_; }
|
||||
|
||||
protected:
|
||||
IndexBuffer* CreateIndexBuffer(
|
||||
const IndexBufferInfo& info,
|
||||
const uint8_t* src_ptr, size_t length) override;
|
||||
VertexBuffer* CreateVertexBuffer(
|
||||
const VertexBufferInfo& info,
|
||||
const uint8_t* src_ptr, size_t length) override;
|
||||
|
||||
protected:
|
||||
ID3D11DeviceContext* context_;
|
||||
ID3D11Device* device_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace d3d11
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_GPU_D3D11_D3D11_BUFFER_CACHE_H_
|
||||
149
src/xenia/gpu/d3d11/d3d11_buffer_resource.cc
Normal file
149
src/xenia/gpu/d3d11/d3d11_buffer_resource.cc
Normal file
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/gpu/d3d11/d3d11_buffer_resource.h>
|
||||
|
||||
#include <xenia/gpu/gpu-private.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_resource_cache.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::gpu;
|
||||
using namespace xe::gpu::d3d11;
|
||||
using namespace xe::gpu::xenos;
|
||||
|
||||
|
||||
D3D11IndexBufferResource::D3D11IndexBufferResource(
|
||||
D3D11ResourceCache* resource_cache,
|
||||
const MemoryRange& memory_range,
|
||||
const Info& info)
|
||||
: IndexBufferResource(memory_range, info),
|
||||
resource_cache_(resource_cache),
|
||||
handle_(nullptr) {
|
||||
}
|
||||
|
||||
D3D11IndexBufferResource::~D3D11IndexBufferResource() {
|
||||
XESAFERELEASE(handle_);
|
||||
}
|
||||
|
||||
int D3D11IndexBufferResource::CreateHandle() {
|
||||
D3D11_BUFFER_DESC buffer_desc;
|
||||
xe_zero_struct(&buffer_desc, sizeof(buffer_desc));
|
||||
buffer_desc.ByteWidth = static_cast<UINT>(memory_range_.length);
|
||||
buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
buffer_desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
HRESULT hr = resource_cache_->device()->CreateBuffer(
|
||||
&buffer_desc, nullptr, &handle_);
|
||||
if (FAILED(hr)) {
|
||||
XELOGW("D3D11: failed to create index buffer");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int D3D11IndexBufferResource::InvalidateRegion(
|
||||
const MemoryRange& memory_range) {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
|
||||
// All that's done so far:
|
||||
XEASSERT(info_.endianness == 0x2);
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE res;
|
||||
HRESULT hr = resource_cache_->context()->Map(
|
||||
handle_, 0, D3D11_MAP_WRITE_DISCARD, 0, &res);
|
||||
if (FAILED(hr)) {
|
||||
XELOGE("D3D11: unable to map index buffer");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (info_.format == INDEX_FORMAT_32BIT) {
|
||||
uint32_t index_count = memory_range_.length / 4;
|
||||
const uint32_t* src = reinterpret_cast<const uint32_t*>(
|
||||
memory_range_.host_base);
|
||||
uint32_t* dest = reinterpret_cast<uint32_t*>(res.pData);
|
||||
for (uint32_t n = 0; n < index_count; n++) {
|
||||
dest[n] = XESWAP32(src[n]);
|
||||
}
|
||||
} else {
|
||||
uint32_t index_count = memory_range_.length / 2;
|
||||
const uint16_t* src = reinterpret_cast<const uint16_t*>(
|
||||
memory_range_.host_base);
|
||||
uint16_t* dest = reinterpret_cast<uint16_t*>(res.pData);
|
||||
for (uint32_t n = 0; n < index_count; n++) {
|
||||
dest[n] = XESWAP16(src[n]);
|
||||
}
|
||||
}
|
||||
resource_cache_->context()->Unmap(handle_, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
D3D11VertexBufferResource::D3D11VertexBufferResource(
|
||||
D3D11ResourceCache* resource_cache,
|
||||
const MemoryRange& memory_range,
|
||||
const Info& info)
|
||||
: VertexBufferResource(memory_range, info),
|
||||
resource_cache_(resource_cache),
|
||||
handle_(nullptr) {
|
||||
}
|
||||
|
||||
D3D11VertexBufferResource::~D3D11VertexBufferResource() {
|
||||
XESAFERELEASE(handle_);
|
||||
}
|
||||
|
||||
int D3D11VertexBufferResource::CreateHandle() {
|
||||
D3D11_BUFFER_DESC buffer_desc;
|
||||
xe_zero_struct(&buffer_desc, sizeof(buffer_desc));
|
||||
buffer_desc.ByteWidth = static_cast<UINT>(memory_range_.length);
|
||||
buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
HRESULT hr = resource_cache_->device()->CreateBuffer(
|
||||
&buffer_desc, nullptr, &handle_);
|
||||
if (FAILED(hr)) {
|
||||
XELOGW("D3D11: failed to create vertex buffer");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int D3D11VertexBufferResource::InvalidateRegion(
|
||||
const MemoryRange& memory_range) {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE res;
|
||||
HRESULT hr = resource_cache_->context()->Map(
|
||||
handle_, 0, D3D11_MAP_WRITE_DISCARD, 0, &res);
|
||||
if (FAILED(hr)) {
|
||||
XELOGE("D3D11: unable to map vertex buffer");
|
||||
return 1;
|
||||
}
|
||||
uint8_t* dest = reinterpret_cast<uint8_t*>(res.pData);
|
||||
|
||||
// TODO(benvanik): rewrite to be faster/special case common/etc
|
||||
uint32_t stride = info_.stride_words;
|
||||
size_t count = (memory_range_.length / 4) / stride;
|
||||
for (size_t n = 0; n < info_.element_count; n++) {
|
||||
const auto& el = info_.elements[n];
|
||||
const uint32_t* src_ptr = (const uint32_t*)(
|
||||
memory_range_.host_base + el.offset_words * 4);
|
||||
uint32_t* dest_ptr = (uint32_t*)(dest + el.offset_words * 4);
|
||||
uint32_t o = 0;
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
for (uint32_t j = 0; j < el.size_words; j++) {
|
||||
dest_ptr[o + j] = XESWAP32(src_ptr[o + j]);
|
||||
}
|
||||
o += stride;
|
||||
}
|
||||
}
|
||||
|
||||
resource_cache_->context()->Unmap(handle_, 0);
|
||||
return 0;
|
||||
}
|
||||
69
src/xenia/gpu/d3d11/d3d11_buffer_resource.h
Normal file
69
src/xenia/gpu/d3d11/d3d11_buffer_resource.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_GPU_D3D11_D3D11_BUFFER_RESOURCE_H_
|
||||
#define XENIA_GPU_D3D11_D3D11_BUFFER_RESOURCE_H_
|
||||
|
||||
#include <xenia/gpu/buffer_resource.h>
|
||||
#include <xenia/gpu/xenos/xenos.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d11 {
|
||||
|
||||
class D3D11ResourceCache;
|
||||
|
||||
|
||||
class D3D11IndexBufferResource : public IndexBufferResource {
|
||||
public:
|
||||
D3D11IndexBufferResource(D3D11ResourceCache* resource_cache,
|
||||
const MemoryRange& memory_range,
|
||||
const Info& info);
|
||||
~D3D11IndexBufferResource() override;
|
||||
|
||||
void* handle() const override { return handle_; }
|
||||
|
||||
protected:
|
||||
int CreateHandle() override;
|
||||
int InvalidateRegion(const MemoryRange& memory_range) override;
|
||||
|
||||
private:
|
||||
D3D11ResourceCache* resource_cache_;
|
||||
ID3D11Buffer* handle_;
|
||||
};
|
||||
|
||||
|
||||
class D3D11VertexBufferResource : public VertexBufferResource {
|
||||
public:
|
||||
D3D11VertexBufferResource(D3D11ResourceCache* resource_cache,
|
||||
const MemoryRange& memory_range,
|
||||
const Info& info);
|
||||
~D3D11VertexBufferResource() override;
|
||||
|
||||
void* handle() const override { return handle_; }
|
||||
|
||||
protected:
|
||||
int CreateHandle() override;
|
||||
int InvalidateRegion(const MemoryRange& memory_range) override;
|
||||
|
||||
private:
|
||||
D3D11ResourceCache* resource_cache_;
|
||||
ID3D11Buffer* handle_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace d3d11
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_GPU_D3D11_D3D11_BUFFER_RESOURCE_H_
|
||||
@@ -10,7 +10,8 @@
|
||||
#include <xenia/gpu/d3d11/d3d11_geometry_shader.h>
|
||||
|
||||
#include <xenia/gpu/gpu-private.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_shader.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_shader_resource.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_shader_translator.h>
|
||||
#include <xenia/gpu/xenos/ucode.h>
|
||||
|
||||
#include <d3dcompiler.h>
|
||||
@@ -22,8 +23,8 @@ using namespace xe::gpu::d3d11;
|
||||
using namespace xe::gpu::xenos;
|
||||
|
||||
|
||||
D3D11GeometryShader::D3D11GeometryShader(ID3D11Device* device, uint64_t hash) :
|
||||
hash_(hash), handle_(NULL) {
|
||||
D3D11GeometryShader::D3D11GeometryShader(ID3D11Device* device)
|
||||
: handle_(nullptr) {
|
||||
device_ = device;
|
||||
device_->AddRef();
|
||||
}
|
||||
@@ -33,7 +34,7 @@ D3D11GeometryShader::~D3D11GeometryShader() {
|
||||
XESAFERELEASE(device_);
|
||||
}
|
||||
|
||||
int D3D11GeometryShader::Prepare(D3D11VertexShader* vertex_shader) {
|
||||
int D3D11GeometryShader::Prepare(D3D11VertexShaderResource* vertex_shader) {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
|
||||
if (handle_) {
|
||||
@@ -94,11 +95,12 @@ ID3D10Blob* D3D11GeometryShader::Compile(const char* shader_source) {
|
||||
if (FLAGS_dump_shaders.size()) {
|
||||
base_path = FLAGS_dump_shaders.c_str();
|
||||
}
|
||||
uint64_t hash = xe_hash64(shader_source, xestrlena(shader_source)); // ?
|
||||
char file_name[XE_MAX_PATH];
|
||||
xesnprintfa(file_name, XECOUNT(file_name),
|
||||
"%s/gen_%.16llX.gs",
|
||||
base_path,
|
||||
hash_);
|
||||
hash);
|
||||
|
||||
if (FLAGS_dump_shaders.size()) {
|
||||
FILE* f = fopen(file_name, "w");
|
||||
@@ -128,7 +130,7 @@ ID3D10Blob* D3D11GeometryShader::Compile(const char* shader_source) {
|
||||
return shader_blob;
|
||||
}
|
||||
|
||||
int D3D11GeometryShader::Generate(D3D11VertexShader* vertex_shader,
|
||||
int D3D11GeometryShader::Generate(D3D11VertexShaderResource* vertex_shader,
|
||||
alloy::StringBuffer* output) {
|
||||
output->Append(
|
||||
"struct VERTEX {\n"
|
||||
@@ -138,7 +140,7 @@ int D3D11GeometryShader::Generate(D3D11VertexShader* vertex_shader,
|
||||
// TODO(benvanik): only add used ones?
|
||||
output->Append(
|
||||
" float4 o[%d] : XE_O;\n",
|
||||
D3D11Shader::MAX_INTERPOLATORS);
|
||||
D3D11ShaderTranslator::kMaxInterpolators);
|
||||
}
|
||||
if (alloc_counts.point_size) {
|
||||
output->Append(
|
||||
@@ -156,15 +158,15 @@ int D3D11GeometryShader::Generate(D3D11VertexShader* vertex_shader,
|
||||
|
||||
|
||||
D3D11PointSpriteGeometryShader::D3D11PointSpriteGeometryShader(
|
||||
ID3D11Device* device, uint64_t hash) :
|
||||
D3D11GeometryShader(device, hash) {
|
||||
ID3D11Device* device) : D3D11GeometryShader(device) {
|
||||
}
|
||||
|
||||
D3D11PointSpriteGeometryShader::~D3D11PointSpriteGeometryShader() {
|
||||
}
|
||||
|
||||
int D3D11PointSpriteGeometryShader::Generate(D3D11VertexShader* vertex_shader,
|
||||
alloy::StringBuffer* output) {
|
||||
int D3D11PointSpriteGeometryShader::Generate(
|
||||
D3D11VertexShaderResource* vertex_shader,
|
||||
alloy::StringBuffer* output) {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
if (D3D11GeometryShader::Generate(vertex_shader, output)) {
|
||||
return 1;
|
||||
@@ -211,15 +213,15 @@ int D3D11PointSpriteGeometryShader::Generate(D3D11VertexShader* vertex_shader,
|
||||
|
||||
|
||||
D3D11RectListGeometryShader::D3D11RectListGeometryShader(
|
||||
ID3D11Device* device, uint64_t hash) :
|
||||
D3D11GeometryShader(device, hash) {
|
||||
ID3D11Device* device) : D3D11GeometryShader(device) {
|
||||
}
|
||||
|
||||
D3D11RectListGeometryShader::~D3D11RectListGeometryShader() {
|
||||
}
|
||||
|
||||
int D3D11RectListGeometryShader::Generate(D3D11VertexShader* vertex_shader,
|
||||
alloy::StringBuffer* output) {
|
||||
int D3D11RectListGeometryShader::Generate(
|
||||
D3D11VertexShaderResource* vertex_shader,
|
||||
alloy::StringBuffer* output) {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
if (D3D11GeometryShader::Generate(vertex_shader, output)) {
|
||||
return 1;
|
||||
@@ -256,15 +258,15 @@ int D3D11RectListGeometryShader::Generate(D3D11VertexShader* vertex_shader,
|
||||
|
||||
|
||||
D3D11QuadListGeometryShader::D3D11QuadListGeometryShader(
|
||||
ID3D11Device* device, uint64_t hash) :
|
||||
D3D11GeometryShader(device, hash) {
|
||||
ID3D11Device* device) : D3D11GeometryShader(device) {
|
||||
}
|
||||
|
||||
D3D11QuadListGeometryShader::~D3D11QuadListGeometryShader() {
|
||||
}
|
||||
|
||||
int D3D11QuadListGeometryShader::Generate(D3D11VertexShader* vertex_shader,
|
||||
alloy::StringBuffer* output) {
|
||||
int D3D11QuadListGeometryShader::Generate(
|
||||
D3D11VertexShaderResource* vertex_shader,
|
||||
alloy::StringBuffer* output) {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
if (D3D11GeometryShader::Generate(vertex_shader, output)) {
|
||||
return 1;
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d11 {
|
||||
|
||||
class D3D11VertexShader;
|
||||
class D3D11VertexShaderResource;
|
||||
|
||||
|
||||
class D3D11GeometryShader {
|
||||
@@ -30,53 +30,52 @@ public:
|
||||
|
||||
ID3D11GeometryShader* handle() const { return handle_; }
|
||||
|
||||
int Prepare(D3D11VertexShader* vertex_shader);
|
||||
int Prepare(D3D11VertexShaderResource* vertex_shader);
|
||||
|
||||
protected:
|
||||
D3D11GeometryShader(ID3D11Device* device, uint64_t hash);
|
||||
D3D11GeometryShader(ID3D11Device* device);
|
||||
|
||||
ID3D10Blob* Compile(const char* shader_source);
|
||||
|
||||
virtual int Generate(D3D11VertexShader* vertex_shader,
|
||||
virtual int Generate(D3D11VertexShaderResource* vertex_shader,
|
||||
alloy::StringBuffer* output);
|
||||
|
||||
protected:
|
||||
ID3D11Device* device_;
|
||||
uint64_t hash_;
|
||||
ID3D11GeometryShader* handle_;
|
||||
};
|
||||
|
||||
|
||||
class D3D11PointSpriteGeometryShader : public D3D11GeometryShader {
|
||||
public:
|
||||
D3D11PointSpriteGeometryShader(ID3D11Device* device, uint64_t hash);
|
||||
virtual ~D3D11PointSpriteGeometryShader();
|
||||
D3D11PointSpriteGeometryShader(ID3D11Device* device);
|
||||
~D3D11PointSpriteGeometryShader() override;
|
||||
|
||||
protected:
|
||||
virtual int Generate(D3D11VertexShader* vertex_shader,
|
||||
alloy::StringBuffer* output);
|
||||
int Generate(D3D11VertexShaderResource* vertex_shader,
|
||||
alloy::StringBuffer* output) override;
|
||||
};
|
||||
|
||||
|
||||
class D3D11RectListGeometryShader : public D3D11GeometryShader {
|
||||
public:
|
||||
D3D11RectListGeometryShader(ID3D11Device* device, uint64_t hash);
|
||||
virtual ~D3D11RectListGeometryShader();
|
||||
D3D11RectListGeometryShader(ID3D11Device* device);
|
||||
~D3D11RectListGeometryShader() override;
|
||||
|
||||
protected:
|
||||
virtual int Generate(D3D11VertexShader* vertex_shader,
|
||||
alloy::StringBuffer* output);
|
||||
int Generate(D3D11VertexShaderResource* vertex_shader,
|
||||
alloy::StringBuffer* output) override;
|
||||
};
|
||||
|
||||
|
||||
class D3D11QuadListGeometryShader : public D3D11GeometryShader {
|
||||
public:
|
||||
D3D11QuadListGeometryShader(ID3D11Device* device, uint64_t hash);
|
||||
virtual ~D3D11QuadListGeometryShader();
|
||||
D3D11QuadListGeometryShader(ID3D11Device* device);
|
||||
~D3D11QuadListGeometryShader() override;
|
||||
|
||||
protected:
|
||||
virtual int Generate(D3D11VertexShader* vertex_shader,
|
||||
alloy::StringBuffer* output);
|
||||
int Generate(D3D11VertexShaderResource* vertex_shader,
|
||||
alloy::StringBuffer* output) override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,8 +13,8 @@
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/gpu/graphics_driver.h>
|
||||
#include <xenia/gpu/shader.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_gpu-private.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_resource_cache.h>
|
||||
#include <xenia/gpu/xenos/xenos.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
@@ -24,13 +24,6 @@ namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d11 {
|
||||
|
||||
class D3D11BufferCache;
|
||||
class D3D11PixelShader;
|
||||
class D3D11ShaderCache;
|
||||
class D3D11TextureCache;
|
||||
struct D3D11TextureView;
|
||||
class D3D11VertexShader;
|
||||
|
||||
|
||||
class D3D11GraphicsDriver : public GraphicsDriver {
|
||||
public:
|
||||
@@ -38,48 +31,32 @@ public:
|
||||
Memory* memory, IDXGISwapChain* swap_chain, ID3D11Device* device);
|
||||
virtual ~D3D11GraphicsDriver();
|
||||
|
||||
virtual void Initialize();
|
||||
ResourceCache* resource_cache() const override { return resource_cache_; }
|
||||
|
||||
virtual void InvalidateState(
|
||||
uint32_t mask);
|
||||
virtual void SetShader(
|
||||
xenos::XE_GPU_SHADER_TYPE type,
|
||||
uint32_t address,
|
||||
uint32_t start,
|
||||
uint32_t length);
|
||||
virtual void DrawIndexBuffer(
|
||||
xenos::XE_GPU_PRIMITIVE_TYPE prim_type,
|
||||
bool index_32bit, uint32_t index_count,
|
||||
uint32_t index_base, uint32_t index_size, uint32_t endianness);
|
||||
virtual void DrawIndexAuto(
|
||||
xenos::XE_GPU_PRIMITIVE_TYPE prim_type,
|
||||
uint32_t index_count);
|
||||
int Initialize() override;
|
||||
|
||||
int Draw(const DrawCommand& command) override;
|
||||
|
||||
// TODO(benvanik): figure this out.
|
||||
virtual int Resolve();
|
||||
int Resolve() override;
|
||||
|
||||
private:
|
||||
int SetupDraw(xenos::XE_GPU_PRIMITIVE_TYPE prim_type);
|
||||
void InitializeInvalidTexture();
|
||||
|
||||
int UpdateState(const DrawCommand& command);
|
||||
int SetupConstantBuffers(const DrawCommand& command);
|
||||
int SetupShaders(const DrawCommand& command);
|
||||
int SetupInputAssembly(const DrawCommand& command);
|
||||
int SetupSamplers(const DrawCommand& command);
|
||||
|
||||
int RebuildRenderTargets(uint32_t width, uint32_t height);
|
||||
int UpdateState(uint32_t state_overrides = 0);
|
||||
int UpdateConstantBuffers();
|
||||
int BindShaders();
|
||||
int PrepareFetchers();
|
||||
int PrepareVertexBuffer(Shader::vtx_buffer_desc_t& desc);
|
||||
int PrepareTextureFetchers();
|
||||
int PrepareTextureSampler(xenos::XE_GPU_SHADER_TYPE shader_type,
|
||||
Shader::tex_buffer_desc_t& desc);
|
||||
int PrepareIndexBuffer(
|
||||
bool index_32bit, uint32_t index_count,
|
||||
uint32_t index_base, uint32_t index_size, uint32_t endianness);
|
||||
|
||||
private:
|
||||
IDXGISwapChain* swap_chain_;
|
||||
ID3D11Device* device_;
|
||||
ID3D11DeviceContext* context_;
|
||||
D3D11BufferCache* buffer_cache_;
|
||||
D3D11ShaderCache* shader_cache_;
|
||||
D3D11TextureCache* texture_cache_;
|
||||
|
||||
D3D11ResourceCache* resource_cache_;
|
||||
|
||||
ID3D11ShaderResourceView* invalid_texture_view_;
|
||||
ID3D11SamplerState* invalid_texture_sampler_state_;
|
||||
@@ -97,9 +74,6 @@ private:
|
||||
} render_targets_;
|
||||
|
||||
struct {
|
||||
D3D11VertexShader* vertex_shader;
|
||||
D3D11PixelShader* pixel_shader;
|
||||
|
||||
struct {
|
||||
ID3D11Buffer* float_constants;
|
||||
ID3D11Buffer* bool_constants;
|
||||
@@ -107,17 +81,7 @@ private:
|
||||
ID3D11Buffer* vs_consts;
|
||||
ID3D11Buffer* gs_consts;
|
||||
} constant_buffers;
|
||||
|
||||
struct {
|
||||
bool enabled;
|
||||
xenos::xe_gpu_texture_fetch_t fetch;
|
||||
D3D11TextureView* view;
|
||||
} texture_fetchers[32];
|
||||
} state_;
|
||||
|
||||
enum StateOverrides {
|
||||
STATE_OVERRIDE_DISABLE_CULLING = (1 << 0),
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -146,12 +146,18 @@ void D3D11GraphicsSystem::Initialize() {
|
||||
XEASSERTNULL(driver_);
|
||||
driver_ = new D3D11GraphicsDriver(
|
||||
memory_, window_->swap_chain(), device_);
|
||||
if (driver_->Initialize()) {
|
||||
XELOGE("Unable to initialize D3D11 driver");
|
||||
return;
|
||||
}
|
||||
|
||||
// Initial vsync kick.
|
||||
DispatchInterruptCallback(0);
|
||||
}
|
||||
|
||||
void D3D11GraphicsSystem::Pump() {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
|
||||
if (swap_pending_) {
|
||||
swap_pending_ = false;
|
||||
|
||||
|
||||
71
src/xenia/gpu/d3d11/d3d11_resource_cache.cc
Normal file
71
src/xenia/gpu/d3d11/d3d11_resource_cache.cc
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/gpu/d3d11/d3d11_resource_cache.h>
|
||||
|
||||
#include <xenia/gpu/gpu-private.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_buffer_resource.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_sampler_state_resource.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_shader_resource.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_texture_resource.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::gpu;
|
||||
using namespace xe::gpu::d3d11;
|
||||
|
||||
|
||||
D3D11ResourceCache::D3D11ResourceCache(Memory* memory,
|
||||
ID3D11Device* device,
|
||||
ID3D11DeviceContext* context)
|
||||
: ResourceCache(memory),
|
||||
device_(device), context_(context) {
|
||||
device_->AddRef();
|
||||
context_->AddRef();
|
||||
}
|
||||
|
||||
D3D11ResourceCache::~D3D11ResourceCache() {
|
||||
XESAFERELEASE(device_);
|
||||
XESAFERELEASE(context_);
|
||||
}
|
||||
|
||||
VertexShaderResource* D3D11ResourceCache::CreateVertexShader(
|
||||
const MemoryRange& memory_range,
|
||||
const VertexShaderResource::Info& info) {
|
||||
return new D3D11VertexShaderResource(this, memory_range, info);
|
||||
}
|
||||
|
||||
PixelShaderResource* D3D11ResourceCache::CreatePixelShader(
|
||||
const MemoryRange& memory_range,
|
||||
const PixelShaderResource::Info& info) {
|
||||
return new D3D11PixelShaderResource(this, memory_range, info);
|
||||
}
|
||||
|
||||
TextureResource* D3D11ResourceCache::CreateTexture(
|
||||
const MemoryRange& memory_range,
|
||||
const TextureResource::Info& info) {
|
||||
return new D3D11TextureResource(this, memory_range, info);
|
||||
}
|
||||
|
||||
SamplerStateResource* D3D11ResourceCache::CreateSamplerState(
|
||||
const SamplerStateResource::Info& info) {
|
||||
return new D3D11SamplerStateResource(this, info);
|
||||
}
|
||||
|
||||
IndexBufferResource* D3D11ResourceCache::CreateIndexBuffer(
|
||||
const MemoryRange& memory_range,
|
||||
const IndexBufferResource::Info& info) {
|
||||
return new D3D11IndexBufferResource(this, memory_range, info);
|
||||
}
|
||||
|
||||
VertexBufferResource* D3D11ResourceCache::CreateVertexBuffer(
|
||||
const MemoryRange& memory_range,
|
||||
const VertexBufferResource::Info& info) {
|
||||
return new D3D11VertexBufferResource(this, memory_range, info);
|
||||
}
|
||||
64
src/xenia/gpu/d3d11/d3d11_resource_cache.h
Normal file
64
src/xenia/gpu/d3d11/d3d11_resource_cache.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_GPU_D3D11_D3D11_RESOURCE_CACHE_H_
|
||||
#define XENIA_GPU_D3D11_D3D11_RESOURCE_CACHE_H_
|
||||
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/gpu/resource_cache.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d11 {
|
||||
|
||||
|
||||
class D3D11ResourceCache : public ResourceCache {
|
||||
public:
|
||||
D3D11ResourceCache(Memory* memory,
|
||||
ID3D11Device* device, ID3D11DeviceContext* context);
|
||||
virtual ~D3D11ResourceCache();
|
||||
|
||||
ID3D11Device* device() const { return device_; }
|
||||
ID3D11DeviceContext* context() const { return context_; }
|
||||
|
||||
protected:
|
||||
VertexShaderResource* CreateVertexShader(
|
||||
const MemoryRange& memory_range,
|
||||
const VertexShaderResource::Info& info) override;
|
||||
PixelShaderResource* CreatePixelShader(
|
||||
const MemoryRange& memory_range,
|
||||
const PixelShaderResource::Info& info) override;
|
||||
TextureResource* CreateTexture(
|
||||
const MemoryRange& memory_range,
|
||||
const TextureResource::Info& info) override;
|
||||
SamplerStateResource* CreateSamplerState(
|
||||
const SamplerStateResource::Info& info) override;
|
||||
IndexBufferResource* CreateIndexBuffer(
|
||||
const MemoryRange& memory_range,
|
||||
const IndexBufferResource::Info& info) override;
|
||||
VertexBufferResource* CreateVertexBuffer(
|
||||
const MemoryRange& memory_range,
|
||||
const VertexBufferResource::Info& info) override;
|
||||
|
||||
private:
|
||||
ID3D11Device* device_;
|
||||
ID3D11DeviceContext* context_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace d3d11
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_GPU_D3D11_D3D11_RESOURCE_CACHE_H_
|
||||
@@ -7,53 +7,36 @@
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/gpu/d3d11/d3d11_texture_cache.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_sampler_state_resource.h>
|
||||
|
||||
#include <xenia/gpu/gpu-private.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_resource_cache.h>
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace xe;
|
||||
using namespace xe::gpu;
|
||||
using namespace xe::gpu::d3d11;
|
||||
using namespace xe::gpu::xenos;
|
||||
|
||||
|
||||
D3D11TextureCache::D3D11TextureCache(
|
||||
Memory* memory,
|
||||
ID3D11DeviceContext* context, ID3D11Device* device)
|
||||
: TextureCache(memory),
|
||||
context_(context), device_(device) {
|
||||
context_->AddRef();
|
||||
device_->AddRef();
|
||||
D3D11SamplerStateResource::D3D11SamplerStateResource(
|
||||
D3D11ResourceCache* resource_cache, const Info& info)
|
||||
: SamplerStateResource(info),
|
||||
resource_cache_(resource_cache),
|
||||
handle_(nullptr) {
|
||||
}
|
||||
|
||||
D3D11TextureCache::~D3D11TextureCache() {
|
||||
for (auto it = samplers_.begin(); it != samplers_.end(); ++it) {
|
||||
auto& cached_state = it->second;
|
||||
XESAFERELEASE(cached_state.state);
|
||||
D3D11SamplerStateResource::~D3D11SamplerStateResource() {
|
||||
XESAFERELEASE(handle_);
|
||||
}
|
||||
|
||||
int D3D11SamplerStateResource::Prepare() {
|
||||
if (handle_) {
|
||||
return 0;
|
||||
}
|
||||
samplers_.clear();
|
||||
|
||||
XESAFERELEASE(device_);
|
||||
XESAFERELEASE(context_);
|
||||
}
|
||||
|
||||
Texture* D3D11TextureCache::CreateTexture(
|
||||
uint32_t address, const uint8_t* host_address,
|
||||
const xenos::xe_gpu_texture_fetch_t& fetch) {
|
||||
return new D3D11Texture(this, address, host_address);
|
||||
}
|
||||
|
||||
ID3D11SamplerState* D3D11TextureCache::GetSamplerState(
|
||||
const xenos::xe_gpu_texture_fetch_t& fetch,
|
||||
const Shader::tex_buffer_desc_t& desc) {
|
||||
D3D11_SAMPLER_DESC sampler_desc;
|
||||
xe_zero_struct(&sampler_desc, sizeof(sampler_desc));
|
||||
uint32_t min_filter = desc.tex_fetch.min_filter == 3 ?
|
||||
fetch.min_filter : desc.tex_fetch.min_filter;
|
||||
uint32_t mag_filter = desc.tex_fetch.mag_filter == 3 ?
|
||||
fetch.mag_filter : desc.tex_fetch.mag_filter;
|
||||
uint32_t mip_filter = desc.tex_fetch.mip_filter == 3 ?
|
||||
fetch.mip_filter : desc.tex_fetch.mip_filter;
|
||||
// MIN, MAG, MIP
|
||||
static const D3D11_FILTER filter_matrix[2][2][3] = {
|
||||
{
|
||||
@@ -87,7 +70,8 @@ ID3D11SamplerState* D3D11TextureCache::GetSamplerState(
|
||||
},
|
||||
},
|
||||
};
|
||||
sampler_desc.Filter = filter_matrix[min_filter][mag_filter][mip_filter];
|
||||
sampler_desc.Filter =
|
||||
filter_matrix[info_.min_filter][info_.mag_filter][info_.mip_filter];
|
||||
static const D3D11_TEXTURE_ADDRESS_MODE mode_map[] = {
|
||||
D3D11_TEXTURE_ADDRESS_WRAP,
|
||||
D3D11_TEXTURE_ADDRESS_MIRROR,
|
||||
@@ -98,9 +82,9 @@ ID3D11SamplerState* D3D11TextureCache::GetSamplerState(
|
||||
D3D11_TEXTURE_ADDRESS_BORDER, // ?
|
||||
D3D11_TEXTURE_ADDRESS_MIRROR, // ?
|
||||
};
|
||||
sampler_desc.AddressU = mode_map[fetch.clamp_x];
|
||||
sampler_desc.AddressV = mode_map[fetch.clamp_y];
|
||||
sampler_desc.AddressW = mode_map[fetch.clamp_z];
|
||||
sampler_desc.AddressU = mode_map[info_.clamp_u];
|
||||
sampler_desc.AddressV = mode_map[info_.clamp_v];
|
||||
sampler_desc.AddressW = mode_map[info_.clamp_w];
|
||||
sampler_desc.MipLODBias;
|
||||
sampler_desc.MaxAnisotropy = 1;
|
||||
sampler_desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||
@@ -111,29 +95,12 @@ ID3D11SamplerState* D3D11TextureCache::GetSamplerState(
|
||||
sampler_desc.MinLOD;
|
||||
sampler_desc.MaxLOD;
|
||||
|
||||
// TODO(benvanik): do this earlier without having to setup the whole struct?
|
||||
size_t hash = hash_combine(
|
||||
sampler_desc.Filter,
|
||||
sampler_desc.AddressU,
|
||||
sampler_desc.AddressV,
|
||||
sampler_desc.AddressW);
|
||||
auto range = samplers_.equal_range(hash);
|
||||
for (auto it = range.first; it != range.second; ++it) {
|
||||
const auto& cached_state = it->second;
|
||||
// TODO(benvanik): faster compare?
|
||||
if (memcmp(&sampler_desc, &cached_state.desc, sizeof(sampler_desc)) == 0) {
|
||||
return cached_state.state;
|
||||
}
|
||||
}
|
||||
|
||||
ID3D11SamplerState* sampler_state = NULL;
|
||||
HRESULT hr = device_->CreateSamplerState(&sampler_desc, &sampler_state);
|
||||
HRESULT hr = resource_cache_->device()->CreateSamplerState(
|
||||
&sampler_desc, &handle_);
|
||||
if (FAILED(hr)) {
|
||||
XELOGE("D3D11: unable to create sampler state");
|
||||
return nullptr;
|
||||
return 1;
|
||||
}
|
||||
|
||||
samplers_.insert({ hash, { sampler_desc, sampler_state } });
|
||||
|
||||
return sampler_state;
|
||||
return 0;
|
||||
}
|
||||
48
src/xenia/gpu/d3d11/d3d11_sampler_state_resource.h
Normal file
48
src/xenia/gpu/d3d11/d3d11_sampler_state_resource.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_GPU_D3D11_D3D11_SAMPLER_STATE_RESOURCE_H_
|
||||
#define XENIA_GPU_D3D11_D3D11_SAMPLER_STATE_RESOURCE_H_
|
||||
|
||||
#include <xenia/gpu/sampler_state_resource.h>
|
||||
#include <xenia/gpu/xenos/ucode.h>
|
||||
#include <xenia/gpu/xenos/xenos.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d11 {
|
||||
|
||||
class D3D11ResourceCache;
|
||||
|
||||
|
||||
class D3D11SamplerStateResource : public SamplerStateResource {
|
||||
public:
|
||||
D3D11SamplerStateResource(D3D11ResourceCache* resource_cache,
|
||||
const Info& info);
|
||||
~D3D11SamplerStateResource() override;
|
||||
|
||||
void* handle() const override { return handle_; }
|
||||
|
||||
int Prepare() override;
|
||||
|
||||
protected:
|
||||
D3D11ResourceCache* resource_cache_;
|
||||
ID3D11SamplerState* handle_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace d3d11
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_GPU_D3D11_D3D11_SAMPLER_STATE_RESOURCE_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,125 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_GPU_D3D11_D3D11_SHADER_H_
|
||||
#define XENIA_GPU_D3D11_D3D11_SHADER_H_
|
||||
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/gpu/shader.h>
|
||||
#include <xenia/gpu/xenos/xenos.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d11 {
|
||||
|
||||
struct Output;
|
||||
|
||||
typedef struct {
|
||||
Output* output;
|
||||
xenos::XE_GPU_SHADER_TYPE type;
|
||||
uint32_t tex_fetch_index;
|
||||
} xe_gpu_translate_ctx_t;
|
||||
|
||||
class D3D11GeometryShader;
|
||||
|
||||
|
||||
class D3D11Shader : public Shader {
|
||||
public:
|
||||
virtual ~D3D11Shader();
|
||||
|
||||
const static uint32_t MAX_INTERPOLATORS = 16;
|
||||
|
||||
protected:
|
||||
D3D11Shader(
|
||||
ID3D11Device* device,
|
||||
xenos::XE_GPU_SHADER_TYPE type,
|
||||
const uint8_t* src_ptr, size_t length,
|
||||
uint64_t hash);
|
||||
|
||||
const char* translated_src() const { return translated_src_; }
|
||||
void set_translated_src(char* value);
|
||||
|
||||
void AppendTextureHeader(Output* output);
|
||||
int TranslateExec(
|
||||
xe_gpu_translate_ctx_t& ctx, const xenos::instr_cf_exec_t& cf);
|
||||
|
||||
ID3D10Blob* Compile(const char* shader_source);
|
||||
|
||||
protected:
|
||||
ID3D11Device* device_;
|
||||
|
||||
char* translated_src_;
|
||||
};
|
||||
|
||||
|
||||
class D3D11VertexShader : public D3D11Shader {
|
||||
public:
|
||||
D3D11VertexShader(
|
||||
ID3D11Device* device,
|
||||
const uint8_t* src_ptr, size_t length,
|
||||
uint64_t hash);
|
||||
virtual ~D3D11VertexShader();
|
||||
|
||||
ID3D11VertexShader* handle() const { return handle_; }
|
||||
ID3D11InputLayout* input_layout() const { return input_layout_; }
|
||||
|
||||
int Prepare(xenos::xe_gpu_program_cntl_t* program_cntl);
|
||||
|
||||
enum GeometryShaderType {
|
||||
POINT_SPRITE_SHADER,
|
||||
RECT_LIST_SHADER,
|
||||
QUAD_LIST_SHADER,
|
||||
|
||||
MAX_GEOMETRY_SHADER_TYPE,
|
||||
};
|
||||
int DemandGeometryShader(GeometryShaderType type,
|
||||
D3D11GeometryShader** out_shader);
|
||||
|
||||
private:
|
||||
const char* Translate(xenos::xe_gpu_program_cntl_t* program_cntl);
|
||||
|
||||
private:
|
||||
ID3D11VertexShader* handle_;
|
||||
ID3D11InputLayout* input_layout_;
|
||||
D3D11GeometryShader* geometry_shaders_[MAX_GEOMETRY_SHADER_TYPE];
|
||||
};
|
||||
|
||||
|
||||
class D3D11PixelShader : public D3D11Shader {
|
||||
public:
|
||||
D3D11PixelShader(
|
||||
ID3D11Device* device,
|
||||
const uint8_t* src_ptr, size_t length,
|
||||
uint64_t hash);
|
||||
virtual ~D3D11PixelShader();
|
||||
|
||||
ID3D11PixelShader* handle() const { return handle_; }
|
||||
|
||||
int Prepare(xenos::xe_gpu_program_cntl_t* program_cntl,
|
||||
D3D11VertexShader* input_shader);
|
||||
|
||||
private:
|
||||
const char* Translate(xenos::xe_gpu_program_cntl_t* program_cntl,
|
||||
D3D11VertexShader* input_shader);
|
||||
|
||||
private:
|
||||
ID3D11PixelShader* handle_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace d3d11
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_GPU_D3D11_D3D11_SHADER_H_
|
||||
@@ -1,45 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/gpu/d3d11/d3d11_shader_cache.h>
|
||||
|
||||
#include <xenia/gpu/d3d11/d3d11_shader.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::gpu;
|
||||
using namespace xe::gpu::d3d11;
|
||||
using namespace xe::gpu::xenos;
|
||||
|
||||
|
||||
D3D11ShaderCache::D3D11ShaderCache(ID3D11Device* device) {
|
||||
device_ = device;
|
||||
device_->AddRef();
|
||||
}
|
||||
|
||||
D3D11ShaderCache::~D3D11ShaderCache() {
|
||||
device_->Release();
|
||||
}
|
||||
|
||||
Shader* D3D11ShaderCache::CreateCore(
|
||||
xenos::XE_GPU_SHADER_TYPE type,
|
||||
const uint8_t* src_ptr, size_t length,
|
||||
uint64_t 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;
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_GPU_D3D11_D3D11_SHADER_CACHE_H_
|
||||
#define XENIA_GPU_D3D11_D3D11_SHADER_CACHE_H_
|
||||
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/gpu/shader_cache.h>
|
||||
|
||||
#include <D3D11.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d11 {
|
||||
|
||||
|
||||
class D3D11ShaderCache : public ShaderCache {
|
||||
public:
|
||||
D3D11ShaderCache(ID3D11Device* device);
|
||||
virtual ~D3D11ShaderCache();
|
||||
|
||||
protected:
|
||||
Shader* CreateCore(
|
||||
xenos::XE_GPU_SHADER_TYPE type,
|
||||
const uint8_t* src_ptr, size_t length,
|
||||
uint64_t hash) override;
|
||||
|
||||
protected:
|
||||
ID3D11Device* device_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace d3d11
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_GPU_D3D11_D3D11_SHADER_CACHE_H_
|
||||
381
src/xenia/gpu/d3d11/d3d11_shader_resource.cc
Normal file
381
src/xenia/gpu/d3d11/d3d11_shader_resource.cc
Normal file
@@ -0,0 +1,381 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/gpu/d3d11/d3d11_shader_resource.h>
|
||||
|
||||
#include <xenia/gpu/gpu-private.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_geometry_shader.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_resource_cache.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_shader_translator.h>
|
||||
#include <xenia/gpu/xenos/ucode.h>
|
||||
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::gpu;
|
||||
using namespace xe::gpu::d3d11;
|
||||
using namespace xe::gpu::xenos;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
ID3D10Blob* D3D11ShaderCompile(XE_GPU_SHADER_TYPE type,
|
||||
const char* shader_source,
|
||||
const char* disasm_source) {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
|
||||
// TODO(benvanik): pick shared runtime mode defines.
|
||||
D3D10_SHADER_MACRO defines[] = {
|
||||
"TEST_DEFINE", "1",
|
||||
0, 0,
|
||||
};
|
||||
|
||||
uint32_t flags1 = 0;
|
||||
flags1 |= D3D10_SHADER_DEBUG;
|
||||
flags1 |= D3D10_SHADER_ENABLE_STRICTNESS;
|
||||
uint32_t flags2 = 0;
|
||||
|
||||
// Create a name.
|
||||
const char* base_path = "";
|
||||
if (FLAGS_dump_shaders.size()) {
|
||||
base_path = FLAGS_dump_shaders.c_str();
|
||||
}
|
||||
size_t hash = xe_hash64(disasm_source, xestrlena(disasm_source)); // ?
|
||||
char file_name[XE_MAX_PATH];
|
||||
xesnprintfa(file_name, XECOUNT(file_name),
|
||||
"%s/gen_%.16llX.%s",
|
||||
base_path,
|
||||
hash,
|
||||
type == XE_GPU_SHADER_TYPE_VERTEX ? "vs" : "ps");
|
||||
|
||||
if (FLAGS_dump_shaders.size()) {
|
||||
FILE* f = fopen(file_name, "w");
|
||||
fprintf(f, shader_source);
|
||||
fprintf(f, "\n\n");
|
||||
fprintf(f, "/*\n");
|
||||
fprintf(f, disasm_source);
|
||||
fprintf(f, " */\n");
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
// Compile shader to bytecode blob.
|
||||
ID3D10Blob* shader_blob = 0;
|
||||
ID3D10Blob* error_blob = 0;
|
||||
HRESULT hr = D3DCompile(
|
||||
shader_source, strlen(shader_source),
|
||||
file_name,
|
||||
defines, nullptr,
|
||||
"main",
|
||||
type == XE_GPU_SHADER_TYPE_VERTEX ? "vs_5_0" : "ps_5_0",
|
||||
flags1, flags2,
|
||||
&shader_blob, &error_blob);
|
||||
if (error_blob) {
|
||||
char* msg = (char*)error_blob->GetBufferPointer();
|
||||
XELOGE("D3D11: shader compile failed with %s", msg);
|
||||
}
|
||||
XESAFERELEASE(error_blob);
|
||||
if (FAILED(hr)) {
|
||||
return nullptr;
|
||||
}
|
||||
return shader_blob;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
D3D11VertexShaderResource::D3D11VertexShaderResource(
|
||||
D3D11ResourceCache* resource_cache,
|
||||
const MemoryRange& memory_range,
|
||||
const Info& info)
|
||||
: VertexShaderResource(memory_range, info),
|
||||
resource_cache_(resource_cache),
|
||||
handle_(nullptr),
|
||||
input_layout_(nullptr),
|
||||
translated_src_(nullptr) {
|
||||
xe_zero_struct(geometry_shaders_, sizeof(geometry_shaders_));
|
||||
}
|
||||
|
||||
D3D11VertexShaderResource::~D3D11VertexShaderResource() {
|
||||
XESAFERELEASE(handle_);
|
||||
XESAFERELEASE(input_layout_);
|
||||
for (int i = 0; i < XECOUNT(geometry_shaders_); ++i) {
|
||||
delete geometry_shaders_[i];
|
||||
}
|
||||
xe_free(translated_src_);
|
||||
}
|
||||
|
||||
int D3D11VertexShaderResource::Prepare(
|
||||
const xe_gpu_program_cntl_t& program_cntl) {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
if (is_prepared_ || handle_) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO(benvanik): look in file based on hash/etc.
|
||||
void* byte_code = NULL;
|
||||
size_t byte_code_length = 0;
|
||||
|
||||
// Translate and compile source.
|
||||
D3D11ShaderTranslator translator;
|
||||
int ret = translator.TranslateVertexShader(this, program_cntl);
|
||||
if (ret) {
|
||||
XELOGE("D3D11: failed to translate vertex shader");
|
||||
return ret;
|
||||
}
|
||||
translated_src_ = xestrdupa(translator.translated_src());
|
||||
|
||||
ID3D10Blob* shader_blob = D3D11ShaderCompile(
|
||||
XE_GPU_SHADER_TYPE_VERTEX, translated_src_, disasm_src());
|
||||
if (!shader_blob) {
|
||||
return 1;
|
||||
}
|
||||
byte_code_length = shader_blob->GetBufferSize();
|
||||
byte_code = xe_malloc(byte_code_length);
|
||||
xe_copy_struct(
|
||||
byte_code, shader_blob->GetBufferPointer(), byte_code_length);
|
||||
XESAFERELEASE(shader_blob);
|
||||
|
||||
// Create shader.
|
||||
HRESULT hr = resource_cache_->device()->CreateVertexShader(
|
||||
byte_code, byte_code_length,
|
||||
nullptr,
|
||||
&handle_);
|
||||
if (FAILED(hr)) {
|
||||
XELOGE("D3D11: failed to create vertex shader");
|
||||
xe_free(byte_code);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create input layout.
|
||||
ret = CreateInputLayout(byte_code, byte_code_length);
|
||||
xe_free(byte_code);
|
||||
if (ret) {
|
||||
return 1;
|
||||
}
|
||||
is_prepared_ = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int D3D11VertexShaderResource::CreateInputLayout(const void* byte_code,
|
||||
size_t byte_code_length) {
|
||||
size_t element_count = 0;
|
||||
const auto& inputs = buffer_inputs();
|
||||
for (uint32_t n = 0; n < inputs.count; n++) {
|
||||
element_count += inputs.descs[n].info.element_count;
|
||||
}
|
||||
if (!element_count) {
|
||||
XELOGW("D3D11: vertex shader with zero inputs -- retaining previous values?");
|
||||
input_layout_ = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
D3D11_INPUT_ELEMENT_DESC* element_descs =
|
||||
(D3D11_INPUT_ELEMENT_DESC*)xe_alloca(
|
||||
sizeof(D3D11_INPUT_ELEMENT_DESC) * element_count);
|
||||
uint32_t el_index = 0;
|
||||
for (uint32_t n = 0; n < inputs.count; n++) {
|
||||
const auto& input = inputs.descs[n];
|
||||
for (uint32_t m = 0; m < input.info.element_count; m++) {
|
||||
const auto& el = input.info.elements[m];
|
||||
uint32_t vb_slot = input.input_index;
|
||||
DXGI_FORMAT vtx_format;
|
||||
switch (el.format) {
|
||||
case FMT_8_8_8_8:
|
||||
if (el.is_normalized) {
|
||||
vtx_format = el.is_signed ?
|
||||
DXGI_FORMAT_R8G8B8A8_SNORM : DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
} else {
|
||||
vtx_format = el.is_signed ?
|
||||
DXGI_FORMAT_R8G8B8A8_SINT : DXGI_FORMAT_R8G8B8A8_UINT;
|
||||
}
|
||||
break;
|
||||
case FMT_2_10_10_10:
|
||||
if (el.is_normalized) {
|
||||
vtx_format = DXGI_FORMAT_R10G10B10A2_UNORM;
|
||||
} else {
|
||||
vtx_format = DXGI_FORMAT_R10G10B10A2_UINT;
|
||||
}
|
||||
break;
|
||||
// DXGI_FORMAT_R11G11B10_FLOAT?
|
||||
case FMT_16_16:
|
||||
if (el.is_normalized) {
|
||||
vtx_format = el.is_signed ?
|
||||
DXGI_FORMAT_R16G16_SNORM : DXGI_FORMAT_R16G16_UNORM;
|
||||
} else {
|
||||
vtx_format = el.is_signed ?
|
||||
DXGI_FORMAT_R16G16_SINT : DXGI_FORMAT_R16G16_UINT;
|
||||
}
|
||||
break;
|
||||
case FMT_16_16_16_16:
|
||||
if (el.is_normalized) {
|
||||
vtx_format = el.is_signed ?
|
||||
DXGI_FORMAT_R16G16B16A16_SNORM : DXGI_FORMAT_R16G16B16A16_UNORM;
|
||||
} else {
|
||||
vtx_format = el.is_signed ?
|
||||
DXGI_FORMAT_R16G16B16A16_SINT : DXGI_FORMAT_R16G16B16A16_UINT;
|
||||
}
|
||||
break;
|
||||
case FMT_16_16_FLOAT:
|
||||
vtx_format = DXGI_FORMAT_R16G16_FLOAT;
|
||||
break;
|
||||
case FMT_16_16_16_16_FLOAT:
|
||||
vtx_format = DXGI_FORMAT_R16G16B16A16_FLOAT;
|
||||
break;
|
||||
case FMT_32:
|
||||
vtx_format = el.is_signed ?
|
||||
DXGI_FORMAT_R32_SINT : DXGI_FORMAT_R32_UINT;
|
||||
break;
|
||||
case FMT_32_32:
|
||||
vtx_format = el.is_signed ?
|
||||
DXGI_FORMAT_R32G32_SINT : DXGI_FORMAT_R32G32_UINT;
|
||||
break;
|
||||
case FMT_32_32_32_32:
|
||||
vtx_format = el.is_signed ?
|
||||
DXGI_FORMAT_R32G32B32A32_SINT : DXGI_FORMAT_R32G32B32A32_UINT;
|
||||
break;
|
||||
case FMT_32_FLOAT:
|
||||
vtx_format = DXGI_FORMAT_R32_FLOAT;
|
||||
break;
|
||||
case FMT_32_32_FLOAT:
|
||||
vtx_format = DXGI_FORMAT_R32G32_FLOAT;
|
||||
break;
|
||||
case FMT_32_32_32_FLOAT:
|
||||
vtx_format = DXGI_FORMAT_R32G32B32_FLOAT;
|
||||
break;
|
||||
case FMT_32_32_32_32_FLOAT:
|
||||
vtx_format = DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||
break;
|
||||
default:
|
||||
XEASSERTALWAYS();
|
||||
break;
|
||||
}
|
||||
element_descs[el_index].SemanticName = "XE_VF";
|
||||
element_descs[el_index].SemanticIndex = el_index;
|
||||
element_descs[el_index].Format = vtx_format;
|
||||
element_descs[el_index].InputSlot = vb_slot;
|
||||
element_descs[el_index].AlignedByteOffset = el.offset_words * 4;
|
||||
element_descs[el_index].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
|
||||
element_descs[el_index].InstanceDataStepRate = 0;
|
||||
el_index++;
|
||||
}
|
||||
}
|
||||
HRESULT hr = resource_cache_->device()->CreateInputLayout(
|
||||
element_descs,
|
||||
(UINT)element_count,
|
||||
byte_code, byte_code_length,
|
||||
&input_layout_);
|
||||
if (FAILED(hr)) {
|
||||
XELOGE("D3D11: failed to create vertex shader input layout");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int D3D11VertexShaderResource::DemandGeometryShader(
|
||||
GeometryShaderType type, D3D11GeometryShader** out_shader) {
|
||||
if (geometry_shaders_[type]) {
|
||||
*out_shader = geometry_shaders_[type];
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Demand generate.
|
||||
auto device = resource_cache_->device();
|
||||
D3D11GeometryShader* shader = nullptr;
|
||||
switch (type) {
|
||||
case POINT_SPRITE_SHADER:
|
||||
shader = new D3D11PointSpriteGeometryShader(device);
|
||||
break;
|
||||
case RECT_LIST_SHADER:
|
||||
shader = new D3D11RectListGeometryShader(device);
|
||||
break;
|
||||
case QUAD_LIST_SHADER:
|
||||
shader = new D3D11QuadListGeometryShader(device);
|
||||
break;
|
||||
default:
|
||||
XEASSERTALWAYS();
|
||||
return 1;
|
||||
}
|
||||
if (!shader) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (shader->Prepare(this)) {
|
||||
delete shader;
|
||||
return 1;
|
||||
}
|
||||
|
||||
geometry_shaders_[type] = shader;
|
||||
*out_shader = geometry_shaders_[type];
|
||||
return 0;
|
||||
}
|
||||
|
||||
D3D11PixelShaderResource::D3D11PixelShaderResource(
|
||||
D3D11ResourceCache* resource_cache,
|
||||
const MemoryRange& memory_range,
|
||||
const Info& info)
|
||||
: PixelShaderResource(memory_range, info),
|
||||
resource_cache_(resource_cache),
|
||||
handle_(nullptr),
|
||||
translated_src_(nullptr) {
|
||||
}
|
||||
|
||||
D3D11PixelShaderResource::~D3D11PixelShaderResource() {
|
||||
XESAFERELEASE(handle_);
|
||||
xe_free(translated_src_);
|
||||
}
|
||||
|
||||
int D3D11PixelShaderResource::Prepare(const xe_gpu_program_cntl_t& program_cntl,
|
||||
VertexShaderResource* input_shader) {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
if (is_prepared_ || handle_) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO(benvanik): look in file based on hash/etc.
|
||||
void* byte_code = NULL;
|
||||
size_t byte_code_length = 0;
|
||||
|
||||
// Translate and compile source.
|
||||
D3D11ShaderTranslator translator;
|
||||
int ret = translator.TranslatePixelShader(this,
|
||||
program_cntl,
|
||||
input_shader->alloc_counts());
|
||||
if (ret) {
|
||||
XELOGE("D3D11: failed to translate pixel shader");
|
||||
return ret;
|
||||
}
|
||||
translated_src_ = xestrdupa(translator.translated_src());
|
||||
|
||||
ID3D10Blob* shader_blob = D3D11ShaderCompile(
|
||||
XE_GPU_SHADER_TYPE_PIXEL, translated_src_, disasm_src());
|
||||
if (!shader_blob) {
|
||||
return 1;
|
||||
}
|
||||
byte_code_length = shader_blob->GetBufferSize();
|
||||
byte_code = xe_malloc(byte_code_length);
|
||||
xe_copy_struct(
|
||||
byte_code, shader_blob->GetBufferPointer(), byte_code_length);
|
||||
XESAFERELEASE(shader_blob);
|
||||
|
||||
// Create shader.
|
||||
HRESULT hr = resource_cache_->device()->CreatePixelShader(
|
||||
byte_code, byte_code_length,
|
||||
nullptr,
|
||||
&handle_);
|
||||
if (FAILED(hr)) {
|
||||
XELOGE("D3D11: failed to create pixel shader");
|
||||
xe_free(byte_code);
|
||||
return 1;
|
||||
}
|
||||
|
||||
xe_free(byte_code);
|
||||
is_prepared_ = true;
|
||||
return 0;
|
||||
}
|
||||
91
src/xenia/gpu/d3d11/d3d11_shader_resource.h
Normal file
91
src/xenia/gpu/d3d11/d3d11_shader_resource.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_GPU_D3D11_D3D11_SHADER_RESOURCE_H_
|
||||
#define XENIA_GPU_D3D11_D3D11_SHADER_RESOURCE_H_
|
||||
|
||||
#include <xenia/gpu/shader_resource.h>
|
||||
#include <xenia/gpu/xenos/xenos.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d11 {
|
||||
|
||||
class D3D11GeometryShader;
|
||||
class D3D11ResourceCache;
|
||||
|
||||
struct Output;
|
||||
typedef struct {
|
||||
Output* output;
|
||||
xenos::XE_GPU_SHADER_TYPE type;
|
||||
uint32_t tex_fetch_index;
|
||||
} xe_gpu_translate_ctx_t;
|
||||
|
||||
class D3D11VertexShaderResource : public VertexShaderResource {
|
||||
public:
|
||||
D3D11VertexShaderResource(D3D11ResourceCache* resource_cache,
|
||||
const MemoryRange& memory_range,
|
||||
const Info& info);
|
||||
~D3D11VertexShaderResource() override;
|
||||
|
||||
void* handle() const override { return handle_; }
|
||||
ID3D11InputLayout* input_layout() const { return input_layout_; }
|
||||
const char* translated_src() const { return translated_src_; }
|
||||
|
||||
int Prepare(const xenos::xe_gpu_program_cntl_t& program_cntl) override;
|
||||
|
||||
enum GeometryShaderType {
|
||||
POINT_SPRITE_SHADER,
|
||||
RECT_LIST_SHADER,
|
||||
QUAD_LIST_SHADER,
|
||||
MAX_GEOMETRY_SHADER_TYPE, // keep at the end
|
||||
};
|
||||
int DemandGeometryShader(GeometryShaderType type,
|
||||
D3D11GeometryShader** out_shader);
|
||||
|
||||
private:
|
||||
int CreateInputLayout(const void* byte_code, size_t byte_code_length);
|
||||
|
||||
D3D11ResourceCache* resource_cache_;
|
||||
ID3D11VertexShader* handle_;
|
||||
ID3D11InputLayout* input_layout_;
|
||||
D3D11GeometryShader* geometry_shaders_[MAX_GEOMETRY_SHADER_TYPE];
|
||||
char* translated_src_;
|
||||
};
|
||||
|
||||
|
||||
class D3D11PixelShaderResource : public PixelShaderResource {
|
||||
public:
|
||||
D3D11PixelShaderResource(D3D11ResourceCache* resource_cache,
|
||||
const MemoryRange& memory_range,
|
||||
const Info& info);
|
||||
~D3D11PixelShaderResource() override;
|
||||
|
||||
void* handle() const override { return handle_; }
|
||||
const char* translated_src() const { return translated_src_; }
|
||||
|
||||
int Prepare(const xenos::xe_gpu_program_cntl_t& program_cntl,
|
||||
VertexShaderResource* vertex_shader) override;
|
||||
|
||||
private:
|
||||
D3D11ResourceCache* resource_cache_;
|
||||
ID3D11PixelShader* handle_;
|
||||
char* translated_src_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace d3d11
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_GPU_D3D11_D3D11_SHADER_RESOURCE_H_
|
||||
1625
src/xenia/gpu/d3d11/d3d11_shader_translator.cc
Normal file
1625
src/xenia/gpu/d3d11/d3d11_shader_translator.cc
Normal file
File diff suppressed because it is too large
Load Diff
125
src/xenia/gpu/d3d11/d3d11_shader_translator.h
Normal file
125
src/xenia/gpu/d3d11/d3d11_shader_translator.h
Normal file
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_GPU_D3D11_D3D11_SHADER_TRANSLATOR_H_
|
||||
#define XENIA_GPU_D3D11_D3D11_SHADER_TRANSLATOR_H_
|
||||
|
||||
#include <xenia/gpu/shader_resource.h>
|
||||
#include <xenia/gpu/xenos/xenos.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d11 {
|
||||
|
||||
|
||||
class D3D11ShaderTranslator {
|
||||
public:
|
||||
const static uint32_t kMaxInterpolators = 16;
|
||||
|
||||
D3D11ShaderTranslator();
|
||||
|
||||
int TranslateVertexShader(VertexShaderResource* vertex_shader,
|
||||
const xenos::xe_gpu_program_cntl_t& program_cntl);
|
||||
int TranslatePixelShader(
|
||||
PixelShaderResource* pixel_shader,
|
||||
const xenos::xe_gpu_program_cntl_t& program_cntl,
|
||||
const VertexShaderResource::AllocCounts& alloc_counts);
|
||||
|
||||
const char* translated_src() const { return buffer_; }
|
||||
|
||||
private:
|
||||
xenos::XE_GPU_SHADER_TYPE type_;
|
||||
uint32_t tex_fetch_index_;
|
||||
const uint32_t* dwords_;
|
||||
|
||||
static const int kCapacity = 64 * 1024;
|
||||
char buffer_[kCapacity];
|
||||
size_t capacity_;
|
||||
size_t offset_;
|
||||
void append(const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int len = xevsnprintfa(buffer_ + offset_, capacity_ - offset_,
|
||||
format, args);
|
||||
va_end(args);
|
||||
offset_ += len;
|
||||
buffer_[offset_] = 0;
|
||||
}
|
||||
|
||||
void AppendTextureHeader(
|
||||
const ShaderResource::SamplerInputs& sampler_inputs);
|
||||
|
||||
void AppendSrcReg(uint32_t num, uint32_t type, uint32_t swiz, uint32_t negate,
|
||||
uint32_t abs);
|
||||
void AppendDestRegName(uint32_t num, uint32_t dst_exp);
|
||||
void AppendDestReg(uint32_t num, uint32_t mask, uint32_t dst_exp);
|
||||
void AppendDestRegPost(uint32_t num, uint32_t mask, uint32_t dst_exp);
|
||||
void PrintSrcReg(uint32_t num, uint32_t type, uint32_t swiz, uint32_t negate,
|
||||
uint32_t abs);
|
||||
void PrintDstReg(uint32_t num, uint32_t mask, uint32_t dst_exp);
|
||||
void PrintExportComment(uint32_t num);
|
||||
|
||||
int TranslateALU(const xenos::instr_alu_t* alu, int sync);
|
||||
int TranslateALU_ADDv(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_MULv(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_MAXv(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_MINv(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_SETXXv(const xenos::instr_alu_t& alu, const char* op);
|
||||
int TranslateALU_SETEv(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_SETGTv(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_SETGTEv(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_SETNEv(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_FRACv(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_TRUNCv(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_FLOORv(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_MULADDv(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_CNDXXv(const xenos::instr_alu_t& alu, const char* op);
|
||||
int TranslateALU_CNDEv(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_CNDGTEv(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_CNDGTv(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_DOT4v(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_DOT3v(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_DOT2ADDv(const xenos::instr_alu_t& alu);
|
||||
// CUBEv
|
||||
int TranslateALU_MAX4v(const xenos::instr_alu_t& alu);
|
||||
// ...
|
||||
int TranslateALU_MAXs(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_MINs(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_SETXXs(const xenos::instr_alu_t& alu, const char* op);
|
||||
int TranslateALU_SETEs(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_SETGTs(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_SETGTEs(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_SETNEs(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_RECIP_IEEE(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_MUL_CONST_0(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_MUL_CONST_1(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_ADD_CONST_0(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_ADD_CONST_1(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_SUB_CONST_0(const xenos::instr_alu_t& alu);
|
||||
int TranslateALU_SUB_CONST_1(const xenos::instr_alu_t& alu);
|
||||
|
||||
void PrintDestFecth(uint32_t dst_reg, uint32_t dst_swiz);
|
||||
void AppendFetchDest(uint32_t dst_reg, uint32_t dst_swiz);
|
||||
int GetFormatComponentCount(uint32_t format);
|
||||
|
||||
int TranslateExec(const xenos::instr_cf_exec_t& cf);
|
||||
int TranslateVertexFetch(const xenos::instr_fetch_vtx_t* vtx, int sync);
|
||||
int TranslateTextureFetch(const xenos::instr_fetch_tex_t* tex, int sync);
|
||||
};
|
||||
|
||||
|
||||
} // namespace d3d11
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_GPU_D3D11_D3D11_SHADER_TRANSLATOR_H_
|
||||
@@ -1,264 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/gpu/d3d11/d3d11_texture.h>
|
||||
|
||||
#include <xenia/gpu/gpu-private.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_texture_cache.h>
|
||||
#include <xenia/gpu/xenos/ucode.h>
|
||||
#include <xenia/gpu/xenos/xenos.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::gpu;
|
||||
using namespace xe::gpu::d3d11;
|
||||
using namespace xe::gpu::xenos;
|
||||
|
||||
|
||||
D3D11Texture::D3D11Texture(D3D11TextureCache* cache, uint32_t address,
|
||||
const uint8_t* host_address)
|
||||
: Texture(address, host_address),
|
||||
cache_(cache) {
|
||||
}
|
||||
|
||||
D3D11Texture::~D3D11Texture() {
|
||||
}
|
||||
|
||||
TextureView* D3D11Texture::FetchNew(
|
||||
const xenos::xe_gpu_texture_fetch_t& fetch) {
|
||||
D3D11TextureView* view = new D3D11TextureView();
|
||||
if (!FillViewInfo(view, fetch)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc;
|
||||
xe_zero_struct(&srv_desc, sizeof(srv_desc));
|
||||
// TODO(benvanik): this may need to be typed on the fetch instruction (float/int/etc?)
|
||||
srv_desc.Format = view->format;
|
||||
|
||||
D3D_SRV_DIMENSION dimension = D3D11_SRV_DIMENSION_UNKNOWN;
|
||||
switch (view->dimensions) {
|
||||
case DIMENSION_1D:
|
||||
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
|
||||
srv_desc.Texture1D.MipLevels = 1;
|
||||
srv_desc.Texture1D.MostDetailedMip = 0;
|
||||
if (!CreateTexture1D(view, fetch)) {
|
||||
XELOGE("D3D11: failed to fetch Texture1D");
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
case DIMENSION_2D:
|
||||
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srv_desc.Texture2D.MipLevels = 1;
|
||||
srv_desc.Texture2D.MostDetailedMip = 0;
|
||||
if (!CreateTexture2D(view, fetch)) {
|
||||
XELOGE("D3D11: failed to fetch Texture2D");
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
case DIMENSION_3D:
|
||||
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
|
||||
srv_desc.Texture3D.MipLevels = 1;
|
||||
srv_desc.Texture3D.MostDetailedMip = 0;
|
||||
if (!CreateTexture3D(view, fetch)) {
|
||||
XELOGE("D3D11: failed to fetch Texture3D");
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
case DIMENSION_CUBE:
|
||||
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
|
||||
srv_desc.TextureCube.MipLevels = 1;
|
||||
srv_desc.TextureCube.MostDetailedMip = 0;
|
||||
if (!CreateTextureCube(view, fetch)) {
|
||||
XELOGE("D3D11: failed to fetch TextureCube");
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
HRESULT hr = cache_->device()->CreateShaderResourceView(
|
||||
view->resource, &srv_desc, &view->srv);
|
||||
if (FAILED(hr)) {
|
||||
XELOGE("D3D11: unable to create texture resource view");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
bool D3D11Texture::FetchDirty(
|
||||
TextureView* view, const xenos::xe_gpu_texture_fetch_t& fetch) {
|
||||
auto d3d_view = static_cast<D3D11TextureView*>(view);
|
||||
switch (view->dimensions) {
|
||||
case DIMENSION_1D:
|
||||
return FetchTexture1D(d3d_view, fetch);
|
||||
case DIMENSION_2D:
|
||||
return FetchTexture2D(d3d_view, fetch);
|
||||
case DIMENSION_3D:
|
||||
return FetchTexture3D(d3d_view, fetch);
|
||||
case DIMENSION_CUBE:
|
||||
return FetchTextureCube(d3d_view, fetch);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool D3D11Texture::CreateTexture1D(
|
||||
D3D11TextureView* view, const xenos::xe_gpu_texture_fetch_t& fetch) {
|
||||
uint32_t width = 1 + fetch.size_1d.width;
|
||||
|
||||
D3D11_TEXTURE1D_DESC texture_desc;
|
||||
xe_zero_struct(&texture_desc, sizeof(texture_desc));
|
||||
texture_desc.Width = width;
|
||||
texture_desc.MipLevels = 1;
|
||||
texture_desc.ArraySize = 1;
|
||||
texture_desc.Format = view->format;
|
||||
texture_desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
texture_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
texture_desc.MiscFlags = 0; // D3D11_RESOURCE_MISC_GENERATE_MIPS?
|
||||
HRESULT hr = cache_->device()->CreateTexture1D(
|
||||
&texture_desc, NULL, (ID3D11Texture1D**)&view->resource);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return FetchTexture1D(view, fetch);
|
||||
}
|
||||
|
||||
bool D3D11Texture::FetchTexture1D(
|
||||
D3D11TextureView* view, const xe_gpu_texture_fetch_t& fetch) {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
|
||||
// TODO(benvanik): upload!
|
||||
XELOGE("D3D11: FetchTexture1D not yet implemented");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool D3D11Texture::CreateTexture2D(
|
||||
D3D11TextureView* view, const xenos::xe_gpu_texture_fetch_t& fetch) {
|
||||
XEASSERTTRUE(fetch.dimension == 1);
|
||||
|
||||
D3D11_TEXTURE2D_DESC texture_desc;
|
||||
xe_zero_struct(&texture_desc, sizeof(texture_desc));
|
||||
texture_desc.Width = view->sizes_2d.output_width;
|
||||
texture_desc.Height = view->sizes_2d.output_height;
|
||||
texture_desc.MipLevels = 1;
|
||||
texture_desc.ArraySize = 1;
|
||||
texture_desc.Format = view->format;
|
||||
texture_desc.SampleDesc.Count = 1;
|
||||
texture_desc.SampleDesc.Quality = 0;
|
||||
texture_desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
texture_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
texture_desc.MiscFlags = 0; // D3D11_RESOURCE_MISC_GENERATE_MIPS?
|
||||
HRESULT hr = cache_->device()->CreateTexture2D(
|
||||
&texture_desc, NULL, (ID3D11Texture2D**)&view->resource);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return FetchTexture2D(view, fetch);
|
||||
}
|
||||
|
||||
bool D3D11Texture::FetchTexture2D(
|
||||
D3D11TextureView* view, const xe_gpu_texture_fetch_t& fetch) {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
|
||||
XEASSERTTRUE(fetch.dimension == 1);
|
||||
|
||||
auto sizes = GetTextureSizes2D(view);
|
||||
|
||||
// TODO(benvanik): all mip levels.
|
||||
D3D11_MAPPED_SUBRESOURCE res;
|
||||
HRESULT hr = cache_->context()->Map(view->resource, 0,
|
||||
D3D11_MAP_WRITE_DISCARD, 0, &res);
|
||||
if (FAILED(hr)) {
|
||||
XELOGE("D3D11: failed to map texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t* src = cache_->memory()->Translate(address_);
|
||||
uint8_t* dest = (uint8_t*)res.pData;
|
||||
|
||||
//memset(dest, 0, output_pitch * (output_height / view->block_size)); // TODO(gibbed): remove me later
|
||||
|
||||
uint32_t output_pitch = res.RowPitch; // (output_width / info.block_size) * info.texel_pitch;
|
||||
if (!fetch.tiled) {
|
||||
dest = (uint8_t*)res.pData;
|
||||
for (uint32_t y = 0; y < sizes.block_height; y++) {
|
||||
for (uint32_t x = 0; x < sizes.logical_pitch; x += view->texel_pitch) {
|
||||
TextureSwap(dest + x, src + x, view->texel_pitch, (XE_GPU_ENDIAN)fetch.endianness);
|
||||
}
|
||||
src += sizes.input_pitch;
|
||||
dest += output_pitch;
|
||||
}
|
||||
} else {
|
||||
auto bpp = (view->texel_pitch >> 2) + ((view->texel_pitch >> 1) >> (view->texel_pitch >> 2));
|
||||
for (uint32_t y = 0, output_base_offset = 0;
|
||||
y < sizes.block_height;
|
||||
y++, output_base_offset += output_pitch) {
|
||||
auto input_base_offset = TiledOffset2DOuter(y, (sizes.input_width / view->block_size), bpp);
|
||||
for (uint32_t x = 0, output_offset = output_base_offset;
|
||||
x < sizes.block_width;
|
||||
x++, output_offset += view->texel_pitch) {
|
||||
auto input_offset = TiledOffset2DInner(x, y, bpp, input_base_offset) >> bpp;
|
||||
TextureSwap(dest + output_offset,
|
||||
src + input_offset * view->texel_pitch,
|
||||
view->texel_pitch, (XE_GPU_ENDIAN)fetch.endianness);
|
||||
}
|
||||
}
|
||||
}
|
||||
cache_->context()->Unmap(view->resource, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D11Texture::CreateTexture3D(
|
||||
D3D11TextureView* view, const xenos::xe_gpu_texture_fetch_t& fetch) {
|
||||
XELOGE("D3D11: CreateTexture3D not yet implemented");
|
||||
XEASSERTALWAYS();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool D3D11Texture::FetchTexture3D(
|
||||
D3D11TextureView* view, const xe_gpu_texture_fetch_t& fetch) {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
|
||||
XELOGE("D3D11: FetchTexture3D not yet implemented");
|
||||
XEASSERTALWAYS();
|
||||
return false;
|
||||
//D3D11_TEXTURE3D_DESC texture_desc;
|
||||
//xe_zero_struct(&texture_desc, sizeof(texture_desc));
|
||||
//texture_desc.Width;
|
||||
//texture_desc.Height;
|
||||
//texture_desc.Depth;
|
||||
//texture_desc.MipLevels;
|
||||
//texture_desc.Format;
|
||||
//texture_desc.Usage;
|
||||
//texture_desc.BindFlags;
|
||||
//texture_desc.CPUAccessFlags;
|
||||
//texture_desc.MiscFlags;
|
||||
//hr = device_->CreateTexture3D(
|
||||
// &texture_desc, &initial_data, (ID3D11Texture3D**)&view->resource);
|
||||
}
|
||||
|
||||
bool D3D11Texture::CreateTextureCube(
|
||||
D3D11TextureView* view, const xenos::xe_gpu_texture_fetch_t& fetch) {
|
||||
XELOGE("D3D11: CreateTextureCube not yet implemented");
|
||||
XEASSERTALWAYS();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool D3D11Texture::FetchTextureCube(
|
||||
D3D11TextureView* view, const xe_gpu_texture_fetch_t& fetch) {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
|
||||
XELOGE("D3D11: FetchTextureCube not yet implemented");
|
||||
XEASSERTALWAYS();
|
||||
return false;
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_GPU_D3D11_D3D11_TEXTURE_H_
|
||||
#define XENIA_GPU_D3D11_D3D11_TEXTURE_H_
|
||||
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/gpu/texture.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d11 {
|
||||
|
||||
class D3D11TextureCache;
|
||||
|
||||
|
||||
struct D3D11TextureView : TextureView {
|
||||
ID3D11Resource* resource;
|
||||
ID3D11ShaderResourceView* srv;
|
||||
|
||||
D3D11TextureView()
|
||||
: resource(nullptr), srv(nullptr) {}
|
||||
virtual ~D3D11TextureView() {
|
||||
XESAFERELEASE(srv);
|
||||
XESAFERELEASE(resource);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class D3D11Texture : public Texture {
|
||||
public:
|
||||
D3D11Texture(D3D11TextureCache* cache, uint32_t address,
|
||||
const uint8_t* host_address);
|
||||
virtual ~D3D11Texture();
|
||||
|
||||
protected:
|
||||
TextureView* FetchNew(
|
||||
const xenos::xe_gpu_texture_fetch_t& fetch) override;
|
||||
bool FetchDirty(
|
||||
TextureView* view, const xenos::xe_gpu_texture_fetch_t& fetch) override;
|
||||
|
||||
bool CreateTexture1D(
|
||||
D3D11TextureView* view, const xenos::xe_gpu_texture_fetch_t& fetch);
|
||||
bool FetchTexture1D(
|
||||
D3D11TextureView* view, const xenos::xe_gpu_texture_fetch_t& fetch);
|
||||
bool CreateTexture2D(
|
||||
D3D11TextureView* view, const xenos::xe_gpu_texture_fetch_t& fetch);
|
||||
bool FetchTexture2D(
|
||||
D3D11TextureView* view, const xenos::xe_gpu_texture_fetch_t& fetch);
|
||||
bool CreateTexture3D(
|
||||
D3D11TextureView* view, const xenos::xe_gpu_texture_fetch_t& fetch);
|
||||
bool FetchTexture3D(
|
||||
D3D11TextureView* view, const xenos::xe_gpu_texture_fetch_t& fetch);
|
||||
bool CreateTextureCube(
|
||||
D3D11TextureView* view, const xenos::xe_gpu_texture_fetch_t& fetch);
|
||||
bool FetchTextureCube(
|
||||
D3D11TextureView* view, const xenos::xe_gpu_texture_fetch_t& fetch);
|
||||
|
||||
D3D11TextureCache* cache_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace d3d11
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_GPU_D3D11_D3D11_TEXTURE_H_
|
||||
@@ -1,61 +0,0 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_GPU_D3D11_D3D11_TEXTURE_CACHE_H_
|
||||
#define XENIA_GPU_D3D11_D3D11_TEXTURE_CACHE_H_
|
||||
|
||||
#include <xenia/core.h>
|
||||
|
||||
#include <xenia/gpu/texture_cache.h>
|
||||
#include <xenia/gpu/shader.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_texture.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d11 {
|
||||
|
||||
|
||||
class D3D11TextureCache : public TextureCache {
|
||||
public:
|
||||
D3D11TextureCache(Memory* memory,
|
||||
ID3D11DeviceContext* context, ID3D11Device* device);
|
||||
virtual ~D3D11TextureCache();
|
||||
|
||||
ID3D11DeviceContext* context() const { return context_; }
|
||||
ID3D11Device* device() const { return device_; }
|
||||
|
||||
ID3D11SamplerState* GetSamplerState(
|
||||
const xenos::xe_gpu_texture_fetch_t& fetch,
|
||||
const Shader::tex_buffer_desc_t& desc);
|
||||
|
||||
protected:
|
||||
Texture* CreateTexture(uint32_t address, const uint8_t* host_address,
|
||||
const xenos::xe_gpu_texture_fetch_t& fetch) override;
|
||||
|
||||
private:
|
||||
ID3D11DeviceContext* context_;
|
||||
ID3D11Device* device_;
|
||||
|
||||
struct CachedSamplerState {
|
||||
D3D11_SAMPLER_DESC desc;
|
||||
ID3D11SamplerState* state;
|
||||
};
|
||||
std::unordered_multimap<size_t, CachedSamplerState> samplers_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace d3d11
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_GPU_D3D11_D3D11_TEXTURE_CACHE_H_
|
||||
219
src/xenia/gpu/d3d11/d3d11_texture_resource.cc
Normal file
219
src/xenia/gpu/d3d11/d3d11_texture_resource.cc
Normal file
@@ -0,0 +1,219 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/gpu/d3d11/d3d11_texture_resource.h>
|
||||
|
||||
#include <xenia/gpu/gpu-private.h>
|
||||
#include <xenia/gpu/d3d11/d3d11_resource_cache.h>
|
||||
|
||||
|
||||
using namespace xe;
|
||||
using namespace xe::gpu;
|
||||
using namespace xe::gpu::d3d11;
|
||||
using namespace xe::gpu::xenos;
|
||||
|
||||
|
||||
D3D11TextureResource::D3D11TextureResource(
|
||||
D3D11ResourceCache* resource_cache,
|
||||
const MemoryRange& memory_range,
|
||||
const Info& info)
|
||||
: TextureResource(memory_range, info),
|
||||
resource_cache_(resource_cache),
|
||||
texture_(nullptr),
|
||||
handle_(nullptr) {
|
||||
}
|
||||
|
||||
D3D11TextureResource::~D3D11TextureResource() {
|
||||
XESAFERELEASE(texture_);
|
||||
XESAFERELEASE(handle_);
|
||||
}
|
||||
|
||||
int D3D11TextureResource::CreateHandle() {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc;
|
||||
xe_zero_struct(&srv_desc, sizeof(srv_desc));
|
||||
// TODO(benvanik): this may need to be typed on the fetch instruction (float/int/etc?)
|
||||
srv_desc.Format = info_.format;
|
||||
|
||||
D3D_SRV_DIMENSION dimension = D3D11_SRV_DIMENSION_UNKNOWN;
|
||||
switch (info_.dimension) {
|
||||
case TEXTURE_DIMENSION_1D:
|
||||
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
|
||||
srv_desc.Texture1D.MipLevels = 1;
|
||||
srv_desc.Texture1D.MostDetailedMip = 0;
|
||||
if (CreateHandle1D()) {
|
||||
XELOGE("D3D11: failed to create Texture1D");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case TEXTURE_DIMENSION_2D:
|
||||
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srv_desc.Texture2D.MipLevels = 1;
|
||||
srv_desc.Texture2D.MostDetailedMip = 0;
|
||||
if (CreateHandle2D()) {
|
||||
XELOGE("D3D11: failed to create Texture2D");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case TEXTURE_DIMENSION_3D:
|
||||
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
|
||||
srv_desc.Texture3D.MipLevels = 1;
|
||||
srv_desc.Texture3D.MostDetailedMip = 0;
|
||||
if (CreateHandle3D()) {
|
||||
XELOGE("D3D11: failed to create Texture3D");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case TEXTURE_DIMENSION_CUBE:
|
||||
srv_desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
|
||||
srv_desc.TextureCube.MipLevels = 1;
|
||||
srv_desc.TextureCube.MostDetailedMip = 0;
|
||||
if (CreateHandleCube()) {
|
||||
XELOGE("D3D11: failed to create TextureCube");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
HRESULT hr = resource_cache_->device()->CreateShaderResourceView(
|
||||
texture_, &srv_desc, &handle_);
|
||||
if (FAILED(hr)) {
|
||||
XELOGE("D3D11: unable to create texture resource view");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int D3D11TextureResource::CreateHandle1D() {
|
||||
uint32_t width = 1 + info_.size_1d.width;
|
||||
|
||||
D3D11_TEXTURE1D_DESC texture_desc;
|
||||
xe_zero_struct(&texture_desc, sizeof(texture_desc));
|
||||
texture_desc.Width = width;
|
||||
texture_desc.MipLevels = 1;
|
||||
texture_desc.ArraySize = 1;
|
||||
texture_desc.Format = info_.format;
|
||||
texture_desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
texture_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
texture_desc.MiscFlags = 0; // D3D11_RESOURCE_MISC_GENERATE_MIPS?
|
||||
HRESULT hr = resource_cache_->device()->CreateTexture1D(
|
||||
&texture_desc, NULL, (ID3D11Texture1D**)&texture_);
|
||||
if (FAILED(hr)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int D3D11TextureResource::CreateHandle2D() {
|
||||
D3D11_TEXTURE2D_DESC texture_desc;
|
||||
xe_zero_struct(&texture_desc, sizeof(texture_desc));
|
||||
texture_desc.Width = info_.size_2d.output_width;
|
||||
texture_desc.Height = info_.size_2d.output_height;
|
||||
texture_desc.MipLevels = 1;
|
||||
texture_desc.ArraySize = 1;
|
||||
texture_desc.Format = info_.format;
|
||||
texture_desc.SampleDesc.Count = 1;
|
||||
texture_desc.SampleDesc.Quality = 0;
|
||||
texture_desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
texture_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
texture_desc.MiscFlags = 0; // D3D11_RESOURCE_MISC_GENERATE_MIPS?
|
||||
HRESULT hr = resource_cache_->device()->CreateTexture2D(
|
||||
&texture_desc, NULL, (ID3D11Texture2D**)&texture_);
|
||||
if (FAILED(hr)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int D3D11TextureResource::CreateHandle3D() {
|
||||
XELOGE("D3D11: CreateTexture3D not yet implemented");
|
||||
XEASSERTALWAYS();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int D3D11TextureResource::CreateHandleCube() {
|
||||
XELOGE("D3D11: CreateTextureCube not yet implemented");
|
||||
XEASSERTALWAYS();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int D3D11TextureResource::InvalidateRegion(const MemoryRange& memory_range) {
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
|
||||
switch (info_.dimension) {
|
||||
case TEXTURE_DIMENSION_1D:
|
||||
return InvalidateRegion1D(memory_range);
|
||||
case TEXTURE_DIMENSION_2D:
|
||||
return InvalidateRegion2D(memory_range);
|
||||
case TEXTURE_DIMENSION_3D:
|
||||
return InvalidateRegion3D(memory_range);
|
||||
case TEXTURE_DIMENSION_CUBE:
|
||||
return InvalidateRegionCube(memory_range);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int D3D11TextureResource::InvalidateRegion1D(const MemoryRange& memory_range) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int D3D11TextureResource::InvalidateRegion2D(const MemoryRange& memory_range) {
|
||||
// TODO(benvanik): all mip levels.
|
||||
D3D11_MAPPED_SUBRESOURCE res;
|
||||
HRESULT hr = resource_cache_->context()->Map(
|
||||
texture_, 0, D3D11_MAP_WRITE_DISCARD, 0, &res);
|
||||
if (FAILED(hr)) {
|
||||
XELOGE("D3D11: failed to map texture");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const uint8_t* src = memory_range_.host_base;
|
||||
uint8_t* dest = (uint8_t*)res.pData;
|
||||
|
||||
uint32_t output_pitch = res.RowPitch; // (output_width / info.block_size) * info.texel_pitch;
|
||||
if (!info_.is_tiled) {
|
||||
dest = (uint8_t*)res.pData;
|
||||
for (uint32_t y = 0; y < info_.size_2d.block_height; y++) {
|
||||
for (uint32_t x = 0; x < info_.size_2d.logical_pitch; x += info_.texel_pitch) {
|
||||
TextureSwap(dest + x, src + x, info_.texel_pitch);
|
||||
}
|
||||
src += info_.size_2d.input_pitch;
|
||||
dest += output_pitch;
|
||||
}
|
||||
} else {
|
||||
auto bpp = (info_.texel_pitch >> 2) + ((info_.texel_pitch >> 1) >> (info_.texel_pitch >> 2));
|
||||
for (uint32_t y = 0, output_base_offset = 0;
|
||||
y < info_.size_2d.block_height;
|
||||
y++, output_base_offset += output_pitch) {
|
||||
auto input_base_offset = TiledOffset2DOuter(y, (info_.size_2d.input_width / info_.block_size), bpp);
|
||||
for (uint32_t x = 0, output_offset = output_base_offset;
|
||||
x < info_.size_2d.block_width;
|
||||
x++, output_offset += info_.texel_pitch) {
|
||||
auto input_offset = TiledOffset2DInner(x, y, bpp, input_base_offset) >> bpp;
|
||||
TextureSwap(dest + output_offset,
|
||||
src + input_offset * info_.texel_pitch,
|
||||
info_.texel_pitch);
|
||||
}
|
||||
}
|
||||
}
|
||||
resource_cache_->context()->Unmap(texture_, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int D3D11TextureResource::InvalidateRegion3D(const MemoryRange& memory_range) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int D3D11TextureResource::InvalidateRegionCube(
|
||||
const MemoryRange& memory_range) {
|
||||
return 1;
|
||||
}
|
||||
60
src/xenia/gpu/d3d11/d3d11_texture_resource.h
Normal file
60
src/xenia/gpu/d3d11/d3d11_texture_resource.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_GPU_D3D11_D3D11_TEXTURE_RESOURCE_H_
|
||||
#define XENIA_GPU_D3D11_D3D11_TEXTURE_RESOURCE_H_
|
||||
|
||||
#include <xenia/gpu/texture_resource.h>
|
||||
#include <xenia/gpu/xenos/xenos.h>
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
namespace d3d11 {
|
||||
|
||||
class D3D11ResourceCache;
|
||||
|
||||
|
||||
class D3D11TextureResource : public TextureResource {
|
||||
public:
|
||||
D3D11TextureResource(D3D11ResourceCache* resource_cache,
|
||||
const MemoryRange& memory_range,
|
||||
const Info& info);
|
||||
~D3D11TextureResource() override;
|
||||
|
||||
void* handle() const override { return handle_; }
|
||||
|
||||
protected:
|
||||
int CreateHandle() override;
|
||||
int CreateHandle1D();
|
||||
int CreateHandle2D();
|
||||
int CreateHandle3D();
|
||||
int CreateHandleCube();
|
||||
|
||||
int InvalidateRegion(const MemoryRange& memory_range) override;
|
||||
int InvalidateRegion1D(const MemoryRange& memory_range);
|
||||
int InvalidateRegion2D(const MemoryRange& memory_range);
|
||||
int InvalidateRegion3D(const MemoryRange& memory_range);
|
||||
int InvalidateRegionCube(const MemoryRange& memory_range);
|
||||
|
||||
private:
|
||||
D3D11ResourceCache* resource_cache_;
|
||||
ID3D11Resource* texture_;
|
||||
ID3D11ShaderResourceView* handle_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace d3d11
|
||||
} // namespace gpu
|
||||
} // namespace xe
|
||||
|
||||
|
||||
#endif // XENIA_GPU_D3D11_D3D11_TEXTURE_RESOURCE_H_
|
||||
@@ -1,10 +1,8 @@
|
||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'd3d11_buffer.cc',
|
||||
'd3d11_buffer.h',
|
||||
'd3d11_buffer_cache.cc',
|
||||
'd3d11_buffer_cache.h',
|
||||
'd3d11_buffer_resource.cc',
|
||||
'd3d11_buffer_resource.h',
|
||||
'd3d11_geometry_shader.cc',
|
||||
'd3d11_geometry_shader.h',
|
||||
'd3d11_gpu-private.h',
|
||||
@@ -16,14 +14,16 @@
|
||||
'd3d11_graphics_system.h',
|
||||
'd3d11_profiler_display.cc',
|
||||
'd3d11_profiler_display.h',
|
||||
'd3d11_shader.cc',
|
||||
'd3d11_shader.h',
|
||||
'd3d11_shader_cache.cc',
|
||||
'd3d11_shader_cache.h',
|
||||
'd3d11_texture.cc',
|
||||
'd3d11_texture.h',
|
||||
'd3d11_texture_cache.cc',
|
||||
'd3d11_texture_cache.h',
|
||||
'd3d11_resource_cache.cc',
|
||||
'd3d11_resource_cache.h',
|
||||
'd3d11_sampler_state_resource.cc',
|
||||
'd3d11_sampler_state_resource.h',
|
||||
'd3d11_shader_resource.cc',
|
||||
'd3d11_shader_resource.h',
|
||||
'd3d11_shader_translator.cc',
|
||||
'd3d11_shader_translator.h',
|
||||
'd3d11_texture_resource.cc',
|
||||
'd3d11_texture_resource.h',
|
||||
'd3d11_window.cc',
|
||||
'd3d11_window.h',
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user