From 42e6a446246e7db048d1962bd5d886abb9b5fe35 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 21 Dec 2014 01:21:39 -0800 Subject: [PATCH] Removing D3D. --- src/xenia/gpu/d3d11/d3d11_buffer_resource.cc | 155 -- src/xenia/gpu/d3d11/d3d11_buffer_resource.h | 67 - src/xenia/gpu/d3d11/d3d11_geometry_shader.cc | 286 --- src/xenia/gpu/d3d11/d3d11_geometry_shader.h | 81 - src/xenia/gpu/d3d11/d3d11_gpu-private.h | 33 - src/xenia/gpu/d3d11/d3d11_gpu.cc | 40 - src/xenia/gpu/d3d11/d3d11_gpu.h | 32 - src/xenia/gpu/d3d11/d3d11_graphics_driver.cc | 924 --------- src/xenia/gpu/d3d11/d3d11_graphics_driver.h | 94 - src/xenia/gpu/d3d11/d3d11_graphics_system.cc | 200 -- src/xenia/gpu/d3d11/d3d11_graphics_system.h | 59 - src/xenia/gpu/d3d11/d3d11_profiler_display.cc | 661 ------- src/xenia/gpu/d3d11/d3d11_profiler_display.h | 80 - src/xenia/gpu/d3d11/d3d11_resource_cache.cc | 71 - src/xenia/gpu/d3d11/d3d11_resource_cache.h | 58 - .../gpu/d3d11/d3d11_sampler_state_resource.cc | 105 -- .../gpu/d3d11/d3d11_sampler_state_resource.h | 47 - src/xenia/gpu/d3d11/d3d11_shader_resource.cc | 375 ---- src/xenia/gpu/d3d11/d3d11_shader_resource.h | 91 - .../gpu/d3d11/d3d11_shader_translator.cc | 1659 ----------------- src/xenia/gpu/d3d11/d3d11_shader_translator.h | 125 -- src/xenia/gpu/d3d11/d3d11_texture_resource.cc | 216 --- src/xenia/gpu/d3d11/d3d11_texture_resource.h | 59 - src/xenia/gpu/d3d11/d3d11_window.cc | 140 -- src/xenia/gpu/d3d11/d3d11_window.h | 52 - src/xenia/gpu/d3d11/sources.gypi | 30 - 26 files changed, 5740 deletions(-) delete mode 100644 src/xenia/gpu/d3d11/d3d11_buffer_resource.cc delete mode 100644 src/xenia/gpu/d3d11/d3d11_buffer_resource.h delete mode 100644 src/xenia/gpu/d3d11/d3d11_geometry_shader.cc delete mode 100644 src/xenia/gpu/d3d11/d3d11_geometry_shader.h delete mode 100644 src/xenia/gpu/d3d11/d3d11_gpu-private.h delete mode 100644 src/xenia/gpu/d3d11/d3d11_gpu.cc delete mode 100644 src/xenia/gpu/d3d11/d3d11_gpu.h delete mode 100644 src/xenia/gpu/d3d11/d3d11_graphics_driver.cc delete mode 100644 src/xenia/gpu/d3d11/d3d11_graphics_driver.h delete mode 100644 src/xenia/gpu/d3d11/d3d11_graphics_system.cc delete mode 100644 src/xenia/gpu/d3d11/d3d11_graphics_system.h delete mode 100644 src/xenia/gpu/d3d11/d3d11_profiler_display.cc delete mode 100644 src/xenia/gpu/d3d11/d3d11_profiler_display.h delete mode 100644 src/xenia/gpu/d3d11/d3d11_resource_cache.cc delete mode 100644 src/xenia/gpu/d3d11/d3d11_resource_cache.h delete mode 100644 src/xenia/gpu/d3d11/d3d11_sampler_state_resource.cc delete mode 100644 src/xenia/gpu/d3d11/d3d11_sampler_state_resource.h delete mode 100644 src/xenia/gpu/d3d11/d3d11_shader_resource.cc delete mode 100644 src/xenia/gpu/d3d11/d3d11_shader_resource.h delete mode 100644 src/xenia/gpu/d3d11/d3d11_shader_translator.cc delete mode 100644 src/xenia/gpu/d3d11/d3d11_shader_translator.h delete mode 100644 src/xenia/gpu/d3d11/d3d11_texture_resource.cc delete mode 100644 src/xenia/gpu/d3d11/d3d11_texture_resource.h delete mode 100644 src/xenia/gpu/d3d11/d3d11_window.cc delete mode 100644 src/xenia/gpu/d3d11/d3d11_window.h delete mode 100644 src/xenia/gpu/d3d11/sources.gypi diff --git a/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc b/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc deleted file mode 100644 index 82c8b4717..000000000 --- a/src/xenia/gpu/d3d11/d3d11_buffer_resource.cc +++ /dev/null @@ -1,155 +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 - -#include - -#include -#include - - -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() { - SafeRelease(handle_); -} - -int D3D11IndexBufferResource::CreateHandle() { - D3D11_BUFFER_DESC buffer_desc; - memset(&buffer_desc, 0, sizeof(buffer_desc)); - buffer_desc.ByteWidth = static_cast(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: - assert_true(info_.endianness == XE_GPU_ENDIAN_8IN16 || - info_.endianness == XE_GPU_ENDIAN_8IN32); - - 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( - memory_range_.host_base); - uint32_t* dest = reinterpret_cast(res.pData); - for (uint32_t n = 0; n < index_count; n++) { - dest[n] = poly::byte_swap(src[n]); - } - } else { - uint32_t index_count = memory_range_.length / 2; - const uint16_t* src = reinterpret_cast( - memory_range_.host_base); - uint16_t* dest = reinterpret_cast(res.pData); - for (uint32_t n = 0; n < index_count; n++) { - dest[n] = poly::byte_swap(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() { - SafeRelease(handle_); -} - -int D3D11VertexBufferResource::CreateHandle() { - D3D11_BUFFER_DESC buffer_desc; - memset(&buffer_desc, 0, sizeof(buffer_desc)); - buffer_desc.ByteWidth = static_cast(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(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; - if (FLAGS_max_draw_elements) { - count = std::min(FLAGS_max_draw_elements, count); - } - 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] = poly::byte_swap(src_ptr[o + j]); - } - o += stride; - } - } - - resource_cache_->context()->Unmap(handle_, 0); - return 0; -} diff --git a/src/xenia/gpu/d3d11/d3d11_buffer_resource.h b/src/xenia/gpu/d3d11/d3d11_buffer_resource.h deleted file mode 100644 index 1860c2e07..000000000 --- a/src/xenia/gpu/d3d11/d3d11_buffer_resource.h +++ /dev/null @@ -1,67 +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_RESOURCE_H_ -#define XENIA_GPU_D3D11_D3D11_BUFFER_RESOURCE_H_ - -#include -#include -#include - -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_ diff --git a/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc b/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc deleted file mode 100644 index 161b716f1..000000000 --- a/src/xenia/gpu/d3d11/d3d11_geometry_shader.cc +++ /dev/null @@ -1,286 +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 - -#include -#include -#include -#include -#include -#include - -#include - - -using namespace xe; -using namespace xe::gpu; -using namespace xe::gpu::d3d11; -using namespace xe::gpu::xenos; - - -D3D11GeometryShader::D3D11GeometryShader(ID3D11Device* device) - : handle_(nullptr) { - device_ = device; - device_->AddRef(); -} - -D3D11GeometryShader::~D3D11GeometryShader() { - SafeRelease(handle_); - SafeRelease(device_); -} - -int D3D11GeometryShader::Prepare(D3D11VertexShaderResource* vertex_shader) { - SCOPE_profile_cpu_f("gpu"); - - if (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. - auto output = new alloy::StringBuffer(); - if (Generate(vertex_shader, output)) { - delete output; - return 1; - } - ID3D10Blob* shader_blob = Compile(output->GetString()); - delete output; - if (!shader_blob) { - return 1; - } - byte_code_length = shader_blob->GetBufferSize(); - byte_code = malloc(byte_code_length); - memcpy(byte_code, shader_blob->GetBufferPointer(), byte_code_length); - SafeRelease(shader_blob); - - // Create shader. - HRESULT hr = device_->CreateGeometryShader( - byte_code, byte_code_length, - NULL, - &handle_); - if (FAILED(hr)) { - XELOGE("D3D11: failed to create geometry shader"); - free(byte_code); - return 1; - } - - return 0; -} - -ID3D10Blob* D3D11GeometryShader::Compile(const char* shader_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(); - } - uint64_t hash = hash64(shader_source, strlen(shader_source)); // ? - char file_name[poly::max_path]; - snprintf(file_name, poly::countof(file_name), "%s/gen_%.16llX.gs", base_path, - hash); - - if (FLAGS_dump_shaders.size()) { - FILE* f = fopen(file_name, "w"); - fprintf(f, shader_source); - 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, NULL, - "main", - "gs_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); - } - SafeRelease(error_blob); - if (FAILED(hr)) { - return NULL; - } - return shader_blob; -} - -int D3D11GeometryShader::Generate(D3D11VertexShaderResource* vertex_shader, - alloy::StringBuffer* output) { - output->Append( - "struct VERTEX {\n" - " float4 oPos : SV_POSITION;\n"); - auto alloc_counts = vertex_shader->alloc_counts(); - if (alloc_counts.params) { - // TODO(benvanik): only add used ones? - output->Append( - " float4 o[%d] : XE_O;\n", - D3D11ShaderTranslator::kMaxInterpolators); - } - if (alloc_counts.point_size) { - output->Append( - " float4 oPointSize : PSIZE;\n"); - } - output->Append( - "};\n"); - - output->Append( - "cbuffer geo_consts {\n" - "};\n"); - - return 0; -} - - -D3D11PointSpriteGeometryShader::D3D11PointSpriteGeometryShader( - ID3D11Device* device) : D3D11GeometryShader(device) { -} - -D3D11PointSpriteGeometryShader::~D3D11PointSpriteGeometryShader() { -} - -int D3D11PointSpriteGeometryShader::Generate( - D3D11VertexShaderResource* vertex_shader, - alloy::StringBuffer* output) { - SCOPE_profile_cpu_f("gpu"); - if (D3D11GeometryShader::Generate(vertex_shader, output)) { - return 1; - } - - auto alloc_counts = vertex_shader->alloc_counts(); - - // TODO(benvanik): fetch default point size from register and use that if - // the VS doesn't write oPointSize. - // TODO(benvanik): clamp to min/max. - // TODO(benvanik): figure out how to see which interpolator gets adjusted. - - output->Append( - "[maxvertexcount(4)]\n" - "void main(point VERTEX input[1], inout TriangleStream output) {\n" - " const float2 offsets[4] = {\n" - " float2(-1.0, 1.0),\n" - " float2( 1.0, 1.0),\n" - " float2(-1.0, -1.0),\n" - " float2( 1.0, -1.0),\n" - " };\n"); - if (alloc_counts.point_size) { - // Point size specified in input. - // TODO(benvanik): pull in psize min/max. - output->Append( - " float psize = max(input[0].oPointSize.x, 1.0);\n"); - } else { - // Point size from register. - // TODO(benvanik): pull in psize. - output->Append( - " float psize = 1.0;\n"); - } - output->Append( - " for (uint n = 0; n < 4; n++) {\n" - " VERTEX v = input[0];\n" - " v.oPos.xy += offsets[n] * psize;\n" - " output.Append(v);\n" - " }\n" - " output.RestartStrip();\n" - "}\n"); - - return 0; -} - - -D3D11RectListGeometryShader::D3D11RectListGeometryShader( - ID3D11Device* device) : D3D11GeometryShader(device) { -} - -D3D11RectListGeometryShader::~D3D11RectListGeometryShader() { -} - -int D3D11RectListGeometryShader::Generate( - D3D11VertexShaderResource* vertex_shader, - alloy::StringBuffer* output) { - SCOPE_profile_cpu_f("gpu"); - if (D3D11GeometryShader::Generate(vertex_shader, output)) { - return 1; - } - - auto alloc_counts = vertex_shader->alloc_counts(); - - output->Append( - "[maxvertexcount(4)]\n" - "void main(triangle VERTEX input[3], inout TriangleStream output) {\n" - " for (uint n = 0; n < 3; n++) {\n" - " VERTEX v = input[n];\n" - " output.Append(v);\n" - " }\n" - " VERTEX v = input[2];\n" - " v.oPos += input[1].oPos - input[0].oPos;\n"); - if (alloc_counts.point_size) { - output->Append( - " v.oPointSize += input[1].oPointSize - input[0].oPointSize;\n"); - } - for (uint32_t n = 0; n < alloc_counts.params; n++) { - // TODO(benvanik): this may be wrong - the count is a bad metric. - output->Append( - " v.o[%d] += input[1].o[%d] - input[0].o[%d];\n", - n, n, n, n); - } - output->Append( - " output.Append(v);\n" - " output.RestartStrip();\n" - "}\n"); - - return 0; -} - - -D3D11QuadListGeometryShader::D3D11QuadListGeometryShader( - ID3D11Device* device) : D3D11GeometryShader(device) { -} - -D3D11QuadListGeometryShader::~D3D11QuadListGeometryShader() { -} - -int D3D11QuadListGeometryShader::Generate( - D3D11VertexShaderResource* vertex_shader, - alloy::StringBuffer* output) { - SCOPE_profile_cpu_f("gpu"); - if (D3D11GeometryShader::Generate(vertex_shader, output)) { - return 1; - } - - output->Append( - "[maxvertexcount(4)]\n" - "void main(lineadj VERTEX input[4], inout TriangleStream output) {\n" - " const uint order[4] = { 0, 1, 3, 2 };\n" - " for (uint n = 0; n < 4; n++) {\n" - " VERTEX v = input[order[n]];\n" - " output.Append(v);\n" - " }\n" - " output.RestartStrip();\n" - "}\n"); - - return 0; -} diff --git a/src/xenia/gpu/d3d11/d3d11_geometry_shader.h b/src/xenia/gpu/d3d11/d3d11_geometry_shader.h deleted file mode 100644 index 66bfd055b..000000000 --- a/src/xenia/gpu/d3d11/d3d11_geometry_shader.h +++ /dev/null @@ -1,81 +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_GEOMETRY_SHADER_H_ -#define XENIA_GPU_D3D11_D3D11_GEOMETRY_SHADER_H_ - -#include -#include -#include - -namespace xe { -namespace gpu { -namespace d3d11 { - -class D3D11VertexShaderResource; - -class D3D11GeometryShader { -public: - virtual ~D3D11GeometryShader(); - - ID3D11GeometryShader* handle() const { return handle_; } - - int Prepare(D3D11VertexShaderResource* vertex_shader); - -protected: - D3D11GeometryShader(ID3D11Device* device); - - ID3D10Blob* Compile(const char* shader_source); - - virtual int Generate(D3D11VertexShaderResource* vertex_shader, - alloy::StringBuffer* output); - -protected: - ID3D11Device* device_; - ID3D11GeometryShader* handle_; -}; - - -class D3D11PointSpriteGeometryShader : public D3D11GeometryShader { -public: - D3D11PointSpriteGeometryShader(ID3D11Device* device); - ~D3D11PointSpriteGeometryShader() override; - -protected: - int Generate(D3D11VertexShaderResource* vertex_shader, - alloy::StringBuffer* output) override; -}; - - -class D3D11RectListGeometryShader : public D3D11GeometryShader { -public: - D3D11RectListGeometryShader(ID3D11Device* device); - ~D3D11RectListGeometryShader() override; - -protected: - int Generate(D3D11VertexShaderResource* vertex_shader, - alloy::StringBuffer* output) override; -}; - - -class D3D11QuadListGeometryShader : public D3D11GeometryShader { -public: - D3D11QuadListGeometryShader(ID3D11Device* device); - ~D3D11QuadListGeometryShader() override; - -protected: - int Generate(D3D11VertexShaderResource* vertex_shader, - alloy::StringBuffer* output) override; -}; - -} // namespace d3d11 -} // namespace gpu -} // namespace xe - -#endif // XENIA_GPU_D3D11_D3D11_SHADER_H_ diff --git a/src/xenia/gpu/d3d11/d3d11_gpu-private.h b/src/xenia/gpu/d3d11/d3d11_gpu-private.h deleted file mode 100644 index defea7f45..000000000 --- a/src/xenia/gpu/d3d11/d3d11_gpu-private.h +++ /dev/null @@ -1,33 +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_GPU_PRIVATE_H_ -#define XENIA_GPU_D3D11_D3D11_GPU_PRIVATE_H_ - -#include - -#include -#include - -namespace xe { -namespace gpu { -namespace d3d11 { - -template -void SafeRelease(T* ptr) { - if (ptr) { - ptr->Release(); - } -} - -} // namespace d3d11 -} // namespace gpu -} // namespace xe - -#endif // XENIA_GPU_D3D11_D3D11_GPU_PRIVATE_H_ diff --git a/src/xenia/gpu/d3d11/d3d11_gpu.cc b/src/xenia/gpu/d3d11/d3d11_gpu.cc deleted file mode 100644 index dbd5bc4c8..000000000 --- a/src/xenia/gpu/d3d11/d3d11_gpu.cc +++ /dev/null @@ -1,40 +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 - -#include - -using namespace xe; -using namespace xe::gpu; -using namespace xe::gpu::d3d11; - -namespace { -void InitializeIfNeeded(); -void CleanupOnShutdown(); - -void InitializeIfNeeded() { - static bool has_initialized = false; - if (has_initialized) { - return; - } - has_initialized = true; - - // - - atexit(CleanupOnShutdown); -} - -void CleanupOnShutdown() {} -} - -std::unique_ptr xe::gpu::d3d11::Create(Emulator* emulator) { - InitializeIfNeeded(); - return std::make_unique(emulator); -} diff --git a/src/xenia/gpu/d3d11/d3d11_gpu.h b/src/xenia/gpu/d3d11/d3d11_gpu.h deleted file mode 100644 index 2357e95d9..000000000 --- a/src/xenia/gpu/d3d11/d3d11_gpu.h +++ /dev/null @@ -1,32 +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_GPU_H_ -#define XENIA_GPU_D3D11_D3D11_GPU_H_ - -#include - -#include - -namespace xe { -class Emulator; -} // namespace xe - -namespace xe { -namespace gpu { -class GraphicsSystem; -namespace d3d11 { - -std::unique_ptr Create(Emulator* emulator); - -} // namespace d3d11 -} // namespace gpu -} // namespace xe - -#endif // XENIA_GPU_D3D11_D3D11_GPU_H_ diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc b/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc deleted file mode 100644 index 88caebe17..000000000 --- a/src/xenia/gpu/d3d11/d3d11_graphics_driver.cc +++ /dev/null @@ -1,924 +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 - -#include -#include -#include -#include -#include -#include -#include -#include - - -using namespace xe; -using namespace xe::gpu; -using namespace xe::gpu::d3d11; -using namespace xe::gpu::xenos; - - -#define XETRACED3D(fmt, ...) if (FLAGS_trace_ring_buffer) XELOGGPU(fmt, ##__VA_ARGS__) - - -D3D11GraphicsDriver::D3D11GraphicsDriver( - Memory* memory, IDXGISwapChain* swap_chain, ID3D11Device* device) : - GraphicsDriver(memory) { - swap_chain_ = swap_chain; - swap_chain_->AddRef(); - device_ = device; - device_->AddRef(); - device_->GetImmediateContext(&context_); - - resource_cache_ = new D3D11ResourceCache(memory, device_, context_); - - memset(&state_, 0, sizeof(state_)); - - memset(&render_targets_, 0, sizeof(render_targets_)); - - HRESULT hr; - D3D11_BUFFER_DESC buffer_desc = {0}; - buffer_desc.Usage = D3D11_USAGE_DYNAMIC; - buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - buffer_desc.ByteWidth = (512 * 4) * sizeof(float); - hr = device_->CreateBuffer( - &buffer_desc, NULL, &state_.constant_buffers.float_constants); - buffer_desc.ByteWidth = (8) * sizeof(int); - hr = device_->CreateBuffer( - &buffer_desc, NULL, &state_.constant_buffers.bool_constants); - buffer_desc.ByteWidth = (32) * sizeof(int); - hr = device_->CreateBuffer( - &buffer_desc, NULL, &state_.constant_buffers.loop_constants); - buffer_desc.ByteWidth = (32) * sizeof(int); - hr = device_->CreateBuffer( - &buffer_desc, NULL, &state_.constant_buffers.vs_consts); - buffer_desc.ByteWidth = (32) * sizeof(int); - hr = device_->CreateBuffer( - &buffer_desc, NULL, &state_.constant_buffers.gs_consts); -} - -D3D11GraphicsDriver::~D3D11GraphicsDriver() { - RebuildRenderTargets(0, 0); - SafeRelease(state_.constant_buffers.float_constants); - SafeRelease(state_.constant_buffers.bool_constants); - SafeRelease(state_.constant_buffers.loop_constants); - SafeRelease(state_.constant_buffers.vs_consts); - SafeRelease(state_.constant_buffers.gs_consts); - for (auto it = rasterizer_state_cache_.begin(); - it != rasterizer_state_cache_.end(); ++it) { - SafeRelease(it->second); - } - for (auto it = blend_state_cache_.begin(); - it != blend_state_cache_.end(); ++it) { - SafeRelease(it->second); - } - for (auto it = depth_stencil_state_cache_.begin(); - it != depth_stencil_state_cache_.end(); ++it) { - SafeRelease(it->second); - } - SafeRelease(invalid_texture_view_); - SafeRelease(invalid_texture_sampler_state_); - delete resource_cache_; - SafeRelease(context_); - SafeRelease(device_); - SafeRelease(swap_chain_); -} - -int D3D11GraphicsDriver::Initialize() { - InitializeInvalidTexture(); - return 0; -} - -void D3D11GraphicsDriver::InitializeInvalidTexture() { - // TODO(benvanik): pattern? - D3D11_TEXTURE2D_DESC texture_desc = {0}; - texture_desc.Width = 4; - texture_desc.Height = 4; - texture_desc.MipLevels = 1; - texture_desc.ArraySize = 1; - texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - texture_desc.SampleDesc.Count = 1; - texture_desc.SampleDesc.Quality = 0; - texture_desc.Usage = D3D11_USAGE_IMMUTABLE; - texture_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - texture_desc.CPUAccessFlags = 0; - texture_desc.MiscFlags = 0; // D3D11_RESOURCE_MISC_GENERATE_MIPS? - uint32_t texture_data[] = { - 0xFF00FF00, 0xFF00FF00, 0xFF00FF00, 0xFF00FF00, - 0xFF00FF00, 0xFF00FF00, 0xFF00FF00, 0xFF00FF00, - 0xFF00FF00, 0xFF00FF00, 0xFF00FF00, 0xFF00FF00, - 0xFF00FF00, 0xFF00FF00, 0xFF00FF00, 0xFF00FF00, - }; - D3D11_SUBRESOURCE_DATA initial_data; - initial_data.SysMemPitch = 4 * texture_desc.Width; - initial_data.SysMemSlicePitch = 0; - initial_data.pSysMem = texture_data; - ID3D11Texture2D* texture = NULL; - HRESULT hr = device_->CreateTexture2D( - &texture_desc, &initial_data, (ID3D11Texture2D**)&texture); - if (FAILED(hr)) { - PFATAL("D3D11: unable to create invalid texture"); - return; - } - - D3D11_SHADER_RESOURCE_VIEW_DESC texture_view_desc = {}; - texture_view_desc.Format = texture_desc.Format; - texture_view_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; - texture_view_desc.Texture2D.MipLevels = 1; - texture_view_desc.Texture2D.MostDetailedMip = 0; - hr = device_->CreateShaderResourceView( - texture, &texture_view_desc, &invalid_texture_view_); - SafeRelease(texture); - - D3D11_SAMPLER_DESC sampler_desc = {}; - sampler_desc.Filter; - sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; - sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; - sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - sampler_desc.MipLODBias; - sampler_desc.MaxAnisotropy = 1; - sampler_desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; - sampler_desc.BorderColor[0]; - sampler_desc.BorderColor[1]; - sampler_desc.BorderColor[2]; - sampler_desc.BorderColor[3]; - sampler_desc.MinLOD; - sampler_desc.MaxLOD; - hr = device_->CreateSamplerState( - &sampler_desc, &invalid_texture_sampler_state_); - if (FAILED(hr)) { - PFATAL("D3D11: unable to create invalid sampler state"); - return; - } -} - -int D3D11GraphicsDriver::Draw(const DrawCommand& command) { - SCOPE_profile_cpu_f("gpu"); - - // Misc state. - if (UpdateState(command)) { - return 1; - } - - // Build constant buffers. - if (SetupConstantBuffers(command)) { - return 1; - } - - // Bind shaders. - if (SetupShaders(command)) { - return 1; - } - - // Bind vertex buffers/index buffer. - if (SetupInputAssembly(command)) { - return 1; - } - - // Bind texture fetchers. - if (SetupSamplers(command)) { - return 1; - } - - if (command.index_buffer) { - // Have an actual index buffer. - XETRACED3D("D3D11: draw indexed %d (indicies [%d,%d] (%d))", - command.prim_type, command.start_index, - command.start_index + command.index_count, command.index_count); - context_->DrawIndexed(command.index_count, command.start_index, - command.base_vertex); - } else { - // Auto draw. - XETRACED3D("D3D11: draw indexed auto %d (indicies [%d,%d] (%d))", - command.prim_type, command.start_index, - command.start_index + command.index_count, command.index_count); - context_->Draw(command.index_count, 0); - } - - return 0; -} - -int D3D11GraphicsDriver::UpdateState(const DrawCommand& command) { - SCOPE_profile_cpu_f("gpu"); - - // Most information comes from here: - // https://chromium.googlesource.com/chromiumos/third_party/mesa/+/6173cc19c45d92ef0b7bc6aa008aa89bb29abbda/src/gallium/drivers/freedreno/freedreno_zsa.c - // http://cgit.freedesktop.org/mesa/mesa/diff/?id=aac7f06ad843eaa696363e8e9c7781ca30cb4914 - // The only differences so far are extra packets for multiple render targets - // and a few modes being switched around. - - RegisterFile& rf = register_file_; - - uint32_t window_scissor_tl = register_file_[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_TL].u32; - uint32_t window_scissor_br = register_file_[XE_GPU_REG_PA_SC_WINDOW_SCISSOR_BR].u32; - //uint32_t window_width = - // (window_scissor_br & 0x7FFF) - (window_scissor_tl & 0x7FFF); - //uint32_t window_height = - // ((window_scissor_br >> 16) & 0x7FFF) - ((window_scissor_tl >> 16) & 0x7FFF); - uint32_t window_width = 1280; - uint32_t window_height = 720; - if (RebuildRenderTargets(window_width, window_height)) { - XELOGE("Unable to rebuild render targets to %d x %d", - window_width, window_height); - return 1; - } - - // RB_SURFACE_INFO ? - - // Enable buffers. - uint32_t enable_mode = register_file_[XE_GPU_REG_RB_MODECONTROL].u32 & 0x7; - // 4 = color + depth - // 6 = copy ? - - // color_info[0-3] has format 8888 - uint32_t color_info[4] = { - register_file_[XE_GPU_REG_RB_COLOR_INFO].u32, - register_file_[XE_GPU_REG_RB_COLOR1_INFO].u32, - register_file_[XE_GPU_REG_RB_COLOR2_INFO].u32, - register_file_[XE_GPU_REG_RB_COLOR3_INFO].u32, - }; - ID3D11RenderTargetView* render_target_views[4] = { 0 }; - for (int n = 0; n < poly::countof(color_info); n++) { - auto cb = render_targets_.color_buffers[n]; - uint32_t color_format = (color_info[n] >> 16) & 0xF; - switch (color_format) { - case 0: // D3DFMT_A8R8G8B8 (or ABGR?) - case 1: - render_target_views[n] = cb.color_view_8888; - break; - default: - // Unknown. - XELOGGPU("Unsupported render target format %d", color_format); - break; - } - } - - // depth_info has format 24_8 - uint32_t depth_info = register_file_[XE_GPU_REG_RB_DEPTH_INFO].u32; - uint32_t depth_format = (depth_info >> 16) & 0x1; - ID3D11DepthStencilView* depth_stencil_view = 0; - switch (depth_format) { - case 0: // D3DFMT_D24S8 - depth_stencil_view = render_targets_.depth_view_d28s8; - break; - default: - case 1: // D3DFMT_D24FS8 - //depth_stencil_view = render_targets_.depth_view_d28fs8; - XELOGGPU("Unsupported depth/stencil format %d", depth_format); - break; - } - // TODO(benvanik): when a game switches does it expect to keep the same - // depth buffer contents? - - // TODO(benvanik): only enable the number of valid render targets. - context_->OMSetRenderTargets(4, render_target_views, depth_stencil_view); - - // Viewport. - // If we have resized the window we will want to change this. - uint32_t window_offset = register_file_[XE_GPU_REG_PA_SC_WINDOW_OFFSET].u32; - // signed? - uint32_t window_offset_x = window_offset & 0x7FFF; - uint32_t window_offset_y = (window_offset >> 16) & 0x7FFF; - - // ? - // TODO(benvanik): figure out how to emulate viewports in D3D11. Could use - // viewport above to scale, though that doesn't support negatives/etc. - uint32_t vte_control = register_file_[XE_GPU_REG_PA_CL_VTE_CNTL].u32; - bool vport_xscale_enable = (vte_control & (1 << 0)) > 0; - float vport_xscale = register_file_[XE_GPU_REG_PA_CL_VPORT_XSCALE].f32; // 640 - bool vport_xoffset_enable = (vte_control & (1 << 1)) > 0; - float vport_xoffset = register_file_[XE_GPU_REG_PA_CL_VPORT_XOFFSET].f32; // 640 - bool vport_yscale_enable = (vte_control & (1 << 2)) > 0; - float vport_yscale = register_file_[XE_GPU_REG_PA_CL_VPORT_YSCALE].f32; // -360 - bool vport_yoffset_enable = (vte_control & (1 << 3)) > 0; - float vport_yoffset = register_file_[XE_GPU_REG_PA_CL_VPORT_YOFFSET].f32; // 360 - bool vport_zscale_enable = (vte_control & (1 << 4)) > 0; - float vport_zscale = register_file_[XE_GPU_REG_PA_CL_VPORT_ZSCALE].f32; // 1 - bool vport_zoffset_enable = (vte_control & (1 << 5)) > 0; - float vport_zoffset = register_file_[XE_GPU_REG_PA_CL_VPORT_ZOFFSET].f32; // 0 - - // TODO(benvanik): compute viewport values. - D3D11_VIEWPORT viewport; - if (vport_xscale_enable) { - // Viewport enabled. - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = 1280; - viewport.Height = 720; - } else { - // Viewport disabled. Geometry shaders will compensate for this. - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = 1280; - viewport.Height = 720; - } - context_->RSSetViewports(1, &viewport); - - // Viewport constants from D3D11VertexShader. - //"cbuffer vs_consts {\n" - //" float4 window;\n" // x,y,w,h - //" float4 viewport_z_enable;\n" // min,(max - min),?,enabled - //" float4 viewport_size;\n" // x,y,w,h - //"};" - // TODO(benvanik): only when viewport changes. - D3D11_MAPPED_SUBRESOURCE res; - context_->Map( - state_.constant_buffers.vs_consts, 0, - D3D11_MAP_WRITE_DISCARD, 0, &res); - float* vsc_buffer = (float*)res.pData; - vsc_buffer[0] = (float)window_offset_x; - vsc_buffer[1] = (float)window_offset_y; - vsc_buffer[2] = (float)window_width; - vsc_buffer[3] = (float)window_height; - vsc_buffer[4] = viewport.MinDepth; - vsc_buffer[5] = viewport.MaxDepth - viewport.MinDepth; - vsc_buffer[6] = 0; // unused - vsc_buffer[7] = vport_xscale_enable ? 1.0f : 0.0f; - vsc_buffer[8] = viewport.TopLeftX; - vsc_buffer[9] = viewport.TopLeftY; - vsc_buffer[10] = viewport.Width; - vsc_buffer[11] = viewport.Height; - context_->Unmap(state_.constant_buffers.vs_consts, 0); - - // Scissoring. - // TODO(benvanik): pull from scissor registers. - // ScissorEnable must be set in raster state above. - uint32_t screen_scissor_tl = register_file_[XE_GPU_REG_PA_SC_SCREEN_SCISSOR_TL].u32; - uint32_t screen_scissor_br = register_file_[XE_GPU_REG_PA_SC_SCREEN_SCISSOR_BR].u32; - if (screen_scissor_tl != 0 && screen_scissor_br != 0x20002000) { - D3D11_RECT scissor_rect; - scissor_rect.top = (screen_scissor_tl >> 16) & 0x7FFF; - scissor_rect.left = screen_scissor_tl & 0x7FFF; - scissor_rect.bottom = (screen_scissor_br >> 16) & 0x7FFF; - scissor_rect.right = screen_scissor_br & 0x7FFF; - context_->RSSetScissorRects(1, &scissor_rect); - } else { - context_->RSSetScissorRects(0, NULL); - } - - if (SetupRasterizerState(command)) { - XELOGE("Unable to setup rasterizer state"); - return 1; - } - if (SetupBlendState(command)) { - XELOGE("Unable to setup blend state"); - return 1; - } - if (SetupDepthStencilState(command)) { - XELOGE("Unable to setup depth/stencil state"); - return 1; - } - - return 0; -} - -int D3D11GraphicsDriver::SetupRasterizerState(const DrawCommand& command) { - uint32_t mode_control = register_file_[XE_GPU_REG_PA_SU_SC_MODE_CNTL].u32; - - // Check cache. - uint64_t key = hash_combine(mode_control); - ID3D11RasterizerState* rasterizer_state = nullptr; - auto it = rasterizer_state_cache_.find(key); - if (it == rasterizer_state_cache_.end()) { - D3D11_RASTERIZER_DESC rasterizer_desc = {}; - rasterizer_desc.FillMode = D3D11_FILL_SOLID; // D3D11_FILL_WIREFRAME; - switch (mode_control & 0x3) { - case 0: - rasterizer_desc.CullMode = D3D11_CULL_NONE; - break; - case 1: - rasterizer_desc.CullMode = D3D11_CULL_FRONT; - break; - case 2: - rasterizer_desc.CullMode = D3D11_CULL_BACK; - break; - } - if (command.prim_type == XE_GPU_PRIMITIVE_TYPE_RECTANGLE_LIST) { - // Rect lists aren't culled. There may be other things they skip too. - rasterizer_desc.CullMode = D3D11_CULL_NONE; - } - rasterizer_desc.FrontCounterClockwise = (mode_control & 0x4) == 0; - rasterizer_desc.DepthBias = 0; - rasterizer_desc.DepthBiasClamp = 0; - rasterizer_desc.SlopeScaledDepthBias = 0; - rasterizer_desc.DepthClipEnable = false; // ? - rasterizer_desc.ScissorEnable = false; - rasterizer_desc.MultisampleEnable = false; - rasterizer_desc.AntialiasedLineEnable = false; - device_->CreateRasterizerState(&rasterizer_desc, &rasterizer_state); - rasterizer_state_cache_.insert({ key, rasterizer_state }); - } else { - rasterizer_state = it->second; - } - - context_->RSSetState(rasterizer_state); - return 0; -} - -int D3D11GraphicsDriver::SetupBlendState(const DrawCommand& command) { - static const D3D11_BLEND blend_map[] = { - /* 0 */ D3D11_BLEND_ZERO, - /* 1 */ D3D11_BLEND_ONE, - /* 2 */ D3D11_BLEND_ZERO, // ? - /* 3 */ D3D11_BLEND_ZERO, // ? - /* 4 */ D3D11_BLEND_SRC_COLOR, - /* 5 */ D3D11_BLEND_INV_SRC_COLOR, - /* 6 */ D3D11_BLEND_SRC_ALPHA, - /* 7 */ D3D11_BLEND_INV_SRC_ALPHA, - /* 8 */ D3D11_BLEND_DEST_COLOR, - /* 9 */ D3D11_BLEND_INV_DEST_COLOR, - /* 10 */ D3D11_BLEND_DEST_ALPHA, - /* 11 */ D3D11_BLEND_INV_DEST_ALPHA, - /* 12 */ D3D11_BLEND_BLEND_FACTOR, - /* 13 */ D3D11_BLEND_INV_BLEND_FACTOR, - /* 14 */ D3D11_BLEND_SRC1_ALPHA, // ? - /* 15 */ D3D11_BLEND_INV_SRC1_ALPHA, // ? - /* 16 */ D3D11_BLEND_SRC_ALPHA_SAT, - }; - static const D3D11_BLEND_OP blend_op_map[] = { - /* 0 */ D3D11_BLEND_OP_ADD, - /* 1 */ D3D11_BLEND_OP_SUBTRACT, - /* 2 */ D3D11_BLEND_OP_MIN, - /* 3 */ D3D11_BLEND_OP_MAX, - /* 4 */ D3D11_BLEND_OP_REV_SUBTRACT, - }; - - // alpha testing -- ALPHAREF, ALPHAFUNC, ALPHATESTENABLE - // Not in D3D11! - // http://msdn.microsoft.com/en-us/library/windows/desktop/bb205120(v=vs.85).aspx - uint32_t color_control = register_file_[XE_GPU_REG_RB_COLORCONTROL].u32; - - uint32_t color_mask = register_file_[XE_GPU_REG_RB_COLOR_MASK].u32; - uint32_t blend_control[4] = { - register_file_[XE_GPU_REG_RB_BLENDCONTROL_0].u32, - register_file_[XE_GPU_REG_RB_BLENDCONTROL_1].u32, - register_file_[XE_GPU_REG_RB_BLENDCONTROL_2].u32, - register_file_[XE_GPU_REG_RB_BLENDCONTROL_3].u32, - }; - - // Check cache. - uint64_t key = hash_combine(color_mask, - blend_control[0], blend_control[1], - blend_control[2], blend_control[3]); - ID3D11BlendState* blend_state = nullptr; - auto it = blend_state_cache_.find(key); - if (it == blend_state_cache_.end()) { - D3D11_BLEND_DESC blend_desc = {0}; - //blend_desc.AlphaToCoverageEnable = false; - // ? - blend_desc.IndependentBlendEnable = true; - for (int n = 0; n < poly::countof(blend_control); n++) { - // A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND - blend_desc.RenderTarget[n].SrcBlend = blend_map[(blend_control[n] & 0x0000001F) >> 0]; - // A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND - blend_desc.RenderTarget[n].DestBlend = blend_map[(blend_control[n] & 0x00001F00) >> 8]; - // A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN - blend_desc.RenderTarget[n].BlendOp = blend_op_map[(blend_control[n] & 0x000000E0) >> 5]; - // A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND - blend_desc.RenderTarget[n].SrcBlendAlpha = blend_map[(blend_control[n] & 0x001F0000) >> 16]; - // A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND - blend_desc.RenderTarget[n].DestBlendAlpha = blend_map[(blend_control[n] & 0x1F000000) >> 24]; - // A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN - blend_desc.RenderTarget[n].BlendOpAlpha = blend_op_map[(blend_control[n] & 0x00E00000) >> 21]; - // A2XX_RB_COLOR_MASK_WRITE_* - blend_desc.RenderTarget[n].RenderTargetWriteMask = (color_mask >> (n * 4)) & 0xF; - // A2XX_RB_COLORCONTROL_BLEND_DISABLE ?? Can't find this! - // Just guess based on actions. - blend_desc.RenderTarget[n].BlendEnable = !( - (blend_desc.RenderTarget[n].SrcBlend == D3D11_BLEND_ONE) && - (blend_desc.RenderTarget[n].DestBlend == D3D11_BLEND_ZERO) && - (blend_desc.RenderTarget[n].BlendOp == D3D11_BLEND_OP_ADD) && - (blend_desc.RenderTarget[n].SrcBlendAlpha == D3D11_BLEND_ONE) && - (blend_desc.RenderTarget[n].DestBlendAlpha == D3D11_BLEND_ZERO) && - (blend_desc.RenderTarget[n].BlendOpAlpha == D3D11_BLEND_OP_ADD)); - } - device_->CreateBlendState(&blend_desc, &blend_state); - blend_state_cache_.insert({ key, blend_state }); - } else { - blend_state = it->second; - } - - float blend_factor[4] = { - register_file_[XE_GPU_REG_RB_BLEND_RED].f32, - register_file_[XE_GPU_REG_RB_BLEND_GREEN].f32, - register_file_[XE_GPU_REG_RB_BLEND_BLUE].f32, - register_file_[XE_GPU_REG_RB_BLEND_ALPHA].f32, - }; - uint32_t sample_mask = 0xFFFFFFFF; // ? - context_->OMSetBlendState(blend_state, blend_factor, sample_mask); - return 0; -} - -int D3D11GraphicsDriver::SetupDepthStencilState(const DrawCommand& command) { - static const D3D11_COMPARISON_FUNC compare_func_map[] = { - /* 0 */ D3D11_COMPARISON_NEVER, - /* 1 */ D3D11_COMPARISON_LESS, - /* 2 */ D3D11_COMPARISON_EQUAL, - /* 3 */ D3D11_COMPARISON_LESS_EQUAL, - /* 4 */ D3D11_COMPARISON_GREATER, - /* 5 */ D3D11_COMPARISON_NOT_EQUAL, - /* 6 */ D3D11_COMPARISON_GREATER_EQUAL, - /* 7 */ D3D11_COMPARISON_ALWAYS, - }; - static const D3D11_STENCIL_OP stencil_op_map[] = { - /* 0 */ D3D11_STENCIL_OP_KEEP, - /* 1 */ D3D11_STENCIL_OP_ZERO, - /* 2 */ D3D11_STENCIL_OP_REPLACE, - /* 3 */ D3D11_STENCIL_OP_INCR_SAT, - /* 4 */ D3D11_STENCIL_OP_DECR_SAT, - /* 5 */ D3D11_STENCIL_OP_INVERT, - /* 6 */ D3D11_STENCIL_OP_INCR, - /* 7 */ D3D11_STENCIL_OP_DECR, - }; - - uint32_t depth_control = register_file_[XE_GPU_REG_RB_DEPTHCONTROL].u32; - uint32_t stencil_ref_mask = register_file_[XE_GPU_REG_RB_STENCILREFMASK].u32; - - // Check cache. - uint64_t key = (uint64_t(depth_control) << 32) | stencil_ref_mask; - ID3D11DepthStencilState* depth_stencil_state = nullptr; - auto it = depth_stencil_state_cache_.find(key); - if (it == depth_stencil_state_cache_.end()) { - D3D11_DEPTH_STENCIL_DESC depth_stencil_desc = {0}; - // A2XX_RB_DEPTHCONTROL_BACKFACE_ENABLE - // ? - // A2XX_RB_DEPTHCONTROL_Z_ENABLE - depth_stencil_desc.DepthEnable = (depth_control & 0x00000002) != 0; - // A2XX_RB_DEPTHCONTROL_Z_WRITE_ENABLE - depth_stencil_desc.DepthWriteMask = (depth_control & 0x00000004) ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; - // A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE - // ? - // A2XX_RB_DEPTHCONTROL_ZFUNC - depth_stencil_desc.DepthFunc = compare_func_map[(depth_control & 0x00000070) >> 4]; - // A2XX_RB_DEPTHCONTROL_STENCIL_ENABLE - depth_stencil_desc.StencilEnable = (depth_control & 0x00000001) != 0; - // RB_STENCILREFMASK_STENCILMASK - depth_stencil_desc.StencilReadMask = (stencil_ref_mask & 0x0000FF00) >> 8; - // RB_STENCILREFMASK_STENCILWRITEMASK - depth_stencil_desc.StencilWriteMask = (stencil_ref_mask & 0x00FF0000) >> 16; - // A2XX_RB_DEPTHCONTROL_STENCILFUNC - depth_stencil_desc.FrontFace.StencilFunc = compare_func_map[(depth_control & 0x00000700) >> 8]; - // A2XX_RB_DEPTHCONTROL_STENCILFAIL - depth_stencil_desc.FrontFace.StencilFailOp = stencil_op_map[(depth_control & 0x00003800) >> 11]; - // A2XX_RB_DEPTHCONTROL_STENCILZPASS - depth_stencil_desc.FrontFace.StencilPassOp = stencil_op_map[(depth_control & 0x0001C000) >> 14]; - // A2XX_RB_DEPTHCONTROL_STENCILZFAIL - depth_stencil_desc.FrontFace.StencilDepthFailOp = stencil_op_map[(depth_control & 0x000E0000) >> 17]; - // A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF - depth_stencil_desc.BackFace.StencilFunc = compare_func_map[(depth_control & 0x00700000) >> 20]; - // A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF - depth_stencil_desc.BackFace.StencilFailOp = stencil_op_map[(depth_control & 0x03800000) >> 23]; - // A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF - depth_stencil_desc.BackFace.StencilPassOp = stencil_op_map[(depth_control & 0x1C000000) >> 26]; - // A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF - depth_stencil_desc.BackFace.StencilDepthFailOp = stencil_op_map[(depth_control & 0xE0000000) >> 29]; - device_->CreateDepthStencilState(&depth_stencil_desc, &depth_stencil_state); - depth_stencil_state_cache_.insert({ key, depth_stencil_state }); - } else { - depth_stencil_state = it->second; - } - - // RB_STENCILREFMASK_STENCILREF - uint32_t stencil_ref = (stencil_ref_mask & 0x000000FF); - context_->OMSetDepthStencilState(depth_stencil_state, stencil_ref); - return 0; -} - -int D3D11GraphicsDriver::SetupConstantBuffers(const DrawCommand& command) { - SCOPE_profile_cpu_f("gpu"); - - D3D11_MAPPED_SUBRESOURCE res; - context_->Map( - state_.constant_buffers.float_constants, 0, - D3D11_MAP_WRITE_DISCARD, 0, &res); - memcpy(res.pData, - command.float4_constants.values, - command.float4_constants.count * 4 * sizeof(float)); - context_->Unmap(state_.constant_buffers.float_constants, 0); - - context_->Map( - state_.constant_buffers.loop_constants, 0, - D3D11_MAP_WRITE_DISCARD, 0, &res); - memcpy(res.pData, - command.loop_constants.values, - command.loop_constants.count * sizeof(int)); - context_->Unmap(state_.constant_buffers.loop_constants, 0); - - context_->Map( - state_.constant_buffers.bool_constants, 0, - D3D11_MAP_WRITE_DISCARD, 0, &res); - memcpy(res.pData, - command.bool_constants.values, - command.bool_constants.count * sizeof(int)); - context_->Unmap(state_.constant_buffers.bool_constants, 0); - - return 0; -} - -int D3D11GraphicsDriver::SetupShaders(const DrawCommand& command) { - SCOPE_profile_cpu_f("gpu"); - - if (command.vertex_shader) { - context_->VSSetShader( - command.vertex_shader->handle_as(), nullptr, 0); - - // Set constant buffers. - ID3D11Buffer* vs_constant_buffers[] = { - state_.constant_buffers.float_constants, - state_.constant_buffers.bool_constants, - state_.constant_buffers.loop_constants, - state_.constant_buffers.vs_consts, - }; - context_->VSSetConstantBuffers( - 0, static_cast(poly::countof(vs_constant_buffers)), - vs_constant_buffers); - - // Setup input layout (as encoded in vertex shader). - auto vs = static_cast(command.vertex_shader); - context_->IASetInputLayout(vs->input_layout()); - } else { - context_->VSSetShader(nullptr, nullptr, 0); - context_->IASetInputLayout(nullptr); - return 1; - } - - // Pixel shader setup. - if (command.pixel_shader) { - context_->PSSetShader( - command.pixel_shader->handle_as(), nullptr, 0); - - // Set constant buffers. - ID3D11Buffer* vs_constant_buffers[] = { - state_.constant_buffers.float_constants, - state_.constant_buffers.bool_constants, - state_.constant_buffers.loop_constants, - }; - context_->PSSetConstantBuffers( - 0, static_cast(poly::countof(vs_constant_buffers)), - vs_constant_buffers); - } else { - context_->PSSetShader(nullptr, nullptr, 0); - return 1; - } - - return 0; -} - -int D3D11GraphicsDriver::SetupInputAssembly(const DrawCommand& command) { - SCOPE_profile_cpu_f("gpu"); - - auto vs = static_cast(command.vertex_shader); - if (!vs) { - return 1; - } - - // Switch primitive topology. - // Some are unsupported on D3D11 and must be emulated. - D3D11_PRIMITIVE_TOPOLOGY primitive_topology; - D3D11GeometryShader* geometry_shader = NULL; - switch (command.prim_type) { - case XE_GPU_PRIMITIVE_TYPE_POINT_LIST: - primitive_topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; - if (vs->DemandGeometryShader( - D3D11VertexShaderResource::POINT_SPRITE_SHADER, &geometry_shader)) { - return 1; - } - break; - case XE_GPU_PRIMITIVE_TYPE_LINE_LIST: - primitive_topology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; - break; - case XE_GPU_PRIMITIVE_TYPE_LINE_STRIP: - primitive_topology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; - break; - case XE_GPU_PRIMITIVE_TYPE_TRIANGLE_LIST: - primitive_topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; - break; - case XE_GPU_PRIMITIVE_TYPE_TRIANGLE_STRIP: - primitive_topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; - break; - case XE_GPU_PRIMITIVE_TYPE_RECTANGLE_LIST: - primitive_topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; - if (vs->DemandGeometryShader( - D3D11VertexShaderResource::RECT_LIST_SHADER, &geometry_shader)) { - return 1; - } - break; - case XE_GPU_PRIMITIVE_TYPE_QUAD_LIST: - primitive_topology = D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ; - if (vs->DemandGeometryShader( - D3D11VertexShaderResource::QUAD_LIST_SHADER, &geometry_shader)) { - return 1; - } - break; - default: - case XE_GPU_PRIMITIVE_TYPE_TRIANGLE_FAN: - case XE_GPU_PRIMITIVE_TYPE_UNKNOWN_07: - case XE_GPU_PRIMITIVE_TYPE_LINE_LOOP: - primitive_topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST; - XELOGE("D3D11: unsupported primitive type %d", command.prim_type); - break; - } - context_->IASetPrimitiveTopology(primitive_topology); - - // Set the geometry shader, if we are emulating a primitive type. - if (geometry_shader) { - context_->GSSetShader(geometry_shader->handle(), NULL, NULL); - context_->GSSetConstantBuffers(0, 1, &state_.constant_buffers.gs_consts); - } else { - context_->GSSetShader(NULL, NULL, NULL); - } - - // Index buffer, if any. May be auto draw. - if (command.index_buffer) { - DXGI_FORMAT format; - switch (command.index_buffer->info().format) { - case INDEX_FORMAT_16BIT: - format = DXGI_FORMAT_R16_UINT; - break; - case INDEX_FORMAT_32BIT: - format = DXGI_FORMAT_R32_UINT; - break; - } - context_->IASetIndexBuffer( - command.index_buffer->handle_as(), - format, 0); - } else { - context_->IASetIndexBuffer(nullptr, DXGI_FORMAT_UNKNOWN, 0); - } - - // All vertex buffers. - for (auto i = 0; i < command.vertex_buffer_count; ++i) { - const auto& vb = command.vertex_buffers[i]; - auto buffer = vb.buffer->handle_as(); - auto stride = vb.stride; - auto offset = vb.offset; - context_->IASetVertexBuffers(vb.input_index, 1, &buffer, - &stride, &offset); - } - - return 0; -} - -int D3D11GraphicsDriver::SetupSamplers(const DrawCommand& command) { - SCOPE_profile_cpu_f("gpu"); - - for (auto i = 0; i < command.vertex_shader_sampler_count; ++i) { - const auto& input = command.vertex_shader_samplers[i]; - if (input.texture) { - auto texture = input.texture->handle_as(); - context_->VSSetShaderResources(input.input_index, 1, &texture); - } else { - context_->VSSetShaderResources(input.input_index, 1, &invalid_texture_view_); - } - if (input.sampler_state) { - auto sampler_state = input.sampler_state->handle_as(); - context_->VSSetSamplers(input.input_index, 1, &sampler_state); - } else { - context_->VSSetSamplers(input.input_index, 1, &invalid_texture_sampler_state_); - } - } - - for (auto i = 0; i < command.pixel_shader_sampler_count; ++i) { - const auto& input = command.pixel_shader_samplers[i]; - if (input.texture) { - auto texture = input.texture->handle_as(); - context_->PSSetShaderResources(input.input_index, 1, &texture); - } else { - context_->PSSetShaderResources(input.input_index, 1, &invalid_texture_view_); - } - if (input.sampler_state) { - auto sampler_state = input.sampler_state->handle_as(); - context_->PSSetSamplers(input.input_index, 1, &sampler_state); - } else { - context_->PSSetSamplers(input.input_index, 1, &invalid_texture_sampler_state_); - } - } - - return 0; -} - -int D3D11GraphicsDriver::RebuildRenderTargets(uint32_t width, - uint32_t height) { - if (width == render_targets_.width && - height == render_targets_.height) { - // Cached copies are good. - return 0; - } - - SCOPE_profile_cpu_f("gpu"); - - // Remove old versions. - for (int n = 0; n < poly::countof(render_targets_.color_buffers); n++) { - auto& cb = render_targets_.color_buffers[n]; - SafeRelease(cb.buffer); - SafeRelease(cb.color_view_8888); - } - SafeRelease(render_targets_.depth_buffer); - SafeRelease(render_targets_.depth_view_d28s8); - SafeRelease(render_targets_.depth_view_d28fs8); - - render_targets_.width = width; - render_targets_.height = height; - - if (!width || !height) { - // This should only happen when cleaning up. - return 0; - } - - for (int n = 0; n < poly::countof(render_targets_.color_buffers); n++) { - auto& cb = render_targets_.color_buffers[n]; - D3D11_TEXTURE2D_DESC color_buffer_desc = {}; - color_buffer_desc.Width = width; - color_buffer_desc.Height = height; - color_buffer_desc.MipLevels = 1; - color_buffer_desc.ArraySize = 1; - color_buffer_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - color_buffer_desc.SampleDesc.Count = 1; - color_buffer_desc.SampleDesc.Quality = 0; - color_buffer_desc.Usage = D3D11_USAGE_DEFAULT; - color_buffer_desc.BindFlags = - D3D11_BIND_SHADER_RESOURCE | - D3D11_BIND_RENDER_TARGET; - color_buffer_desc.CPUAccessFlags = 0; - color_buffer_desc.MiscFlags = 0; - device_->CreateTexture2D( - &color_buffer_desc, NULL, &cb.buffer); - - D3D11_RENDER_TARGET_VIEW_DESC render_target_view_desc; - memset(&render_target_view_desc, 0, sizeof(render_target_view_desc)); - render_target_view_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - render_target_view_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - // render_target_view_desc.Buffer ? - device_->CreateRenderTargetView( - cb.buffer, - &render_target_view_desc, - &cb.color_view_8888); - } - - D3D11_TEXTURE2D_DESC depth_stencil_desc = {}; - depth_stencil_desc.Width = width; - depth_stencil_desc.Height = height; - depth_stencil_desc.MipLevels = 1; - depth_stencil_desc.ArraySize = 1; - depth_stencil_desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - depth_stencil_desc.SampleDesc.Count = 1; - depth_stencil_desc.SampleDesc.Quality = 0; - depth_stencil_desc.Usage = D3D11_USAGE_DEFAULT; - depth_stencil_desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - depth_stencil_desc.CPUAccessFlags = 0; - depth_stencil_desc.MiscFlags = 0; - device_->CreateTexture2D( - &depth_stencil_desc, NULL, &render_targets_.depth_buffer); - - D3D11_DEPTH_STENCIL_VIEW_DESC depth_stencil_view_desc = {}; - depth_stencil_view_desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; - depth_stencil_view_desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - depth_stencil_view_desc.Flags = 0; - device_->CreateDepthStencilView( - render_targets_.depth_buffer, - &depth_stencil_view_desc, - &render_targets_.depth_view_d28s8); - - return 0; -} - -int D3D11GraphicsDriver::Resolve() { - SCOPE_profile_cpu_f("gpu"); - - // No clue how this is supposed to work yet. - ID3D11Texture2D* back_buffer = 0; - swap_chain_->GetBuffer(0, __uuidof(ID3D11Texture2D), - (LPVOID*)&back_buffer); - D3D11_TEXTURE2D_DESC desc; - back_buffer->GetDesc(&desc); - if (desc.Width == render_targets_.width && - desc.Height == render_targets_.height) { - // Same size/format, so copy quickly. - context_->CopyResource(back_buffer, render_targets_.color_buffers[0].buffer); - } else { - // TODO(benvanik): scale size using a quad draw. - } - SafeRelease(back_buffer); - - // TODO(benvanik): remove! - float color[4] = { 0.5f, 0.5f, 0.0f, 1.0f }; - context_->ClearRenderTargetView( - render_targets_.color_buffers[0].color_view_8888, color); - // TODO(benvanik): take clear values from register - context_->ClearDepthStencilView( - render_targets_.depth_view_d28s8, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0); - - return 0; -} diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_driver.h b/src/xenia/gpu/d3d11/d3d11_graphics_driver.h deleted file mode 100644 index 6fe34801a..000000000 --- a/src/xenia/gpu/d3d11/d3d11_graphics_driver.h +++ /dev/null @@ -1,94 +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_GRAPHICS_DRIVER_H_ -#define XENIA_GPU_D3D11_D3D11_GRAPHICS_DRIVER_H_ - -#include - -#include -#include -#include -#include - -namespace xe { -namespace gpu { -namespace d3d11 { - -class D3D11GraphicsDriver : public GraphicsDriver { -public: - D3D11GraphicsDriver( - Memory* memory, IDXGISwapChain* swap_chain, ID3D11Device* device); - virtual ~D3D11GraphicsDriver(); - - ResourceCache* resource_cache() const override { return resource_cache_; } - - int Initialize() override; - - int Draw(const DrawCommand& command) override; - - // TODO(benvanik): figure this out. - int Resolve() override; - -private: - void InitializeInvalidTexture(); - - int UpdateState(const DrawCommand& command); - int SetupRasterizerState(const DrawCommand& command); - int SetupBlendState(const DrawCommand& command); - int SetupDepthStencilState(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); - -private: - IDXGISwapChain* swap_chain_; - ID3D11Device* device_; - ID3D11DeviceContext* context_; - - D3D11ResourceCache* resource_cache_; - - ID3D11ShaderResourceView* invalid_texture_view_; - ID3D11SamplerState* invalid_texture_sampler_state_; - - std::unordered_map rasterizer_state_cache_; - std::unordered_map blend_state_cache_; - std::unordered_map depth_stencil_state_cache_; - - struct { - uint32_t width; - uint32_t height; - struct { - ID3D11Texture2D* buffer; - ID3D11RenderTargetView* color_view_8888; - } color_buffers[4]; - ID3D11Texture2D* depth_buffer; - ID3D11DepthStencilView* depth_view_d28s8; - ID3D11DepthStencilView* depth_view_d28fs8; - } render_targets_; - - struct { - struct { - ID3D11Buffer* float_constants; - ID3D11Buffer* bool_constants; - ID3D11Buffer* loop_constants; - ID3D11Buffer* vs_consts; - ID3D11Buffer* gs_consts; - } constant_buffers; - } state_; -}; - -} // namespace d3d11 -} // namespace gpu -} // namespace xe - -#endif // XENIA_GPU_D3D11_D3D11_GRAPHICS_DRIVER_H_ diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_system.cc b/src/xenia/gpu/d3d11/d3d11_graphics_system.cc deleted file mode 100644 index 7f357334a..000000000 --- a/src/xenia/gpu/d3d11/d3d11_graphics_system.cc +++ /dev/null @@ -1,200 +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 - -#include - -#include -#include -#include -#include -#include - - -using namespace xe; -using namespace xe::gpu; -using namespace xe::gpu::d3d11; - - -D3D11GraphicsSystem::D3D11GraphicsSystem(Emulator* emulator) - : GraphicsSystem(emulator), - window_(nullptr), dxgi_factory_(nullptr), device_(nullptr), - timer_queue_(nullptr), vsync_timer_(nullptr) { -} - -D3D11GraphicsSystem::~D3D11GraphicsSystem() { -} - -void D3D11GraphicsSystem::Initialize() { - GraphicsSystem::Initialize(); - - assert_null(timer_queue_); - assert_null(vsync_timer_); - - timer_queue_ = CreateTimerQueue(); - CreateTimerQueueTimer( - &vsync_timer_, - timer_queue_, - (WAITORTIMERCALLBACK)VsyncCallback, - this, - 16, - 16, - WT_EXECUTEINTIMERTHREAD); - - // Create DXGI factory so we can get a swap chain/etc. - HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), - (void**)&dxgi_factory_); - if (FAILED(hr)) { - XELOGE("CreateDXGIFactory1 failed with %.8X", hr); - exit(1); - return; - } - - // Find the best adapter. - // TODO(benvanik): enable nvperfhud/etc. - IDXGIAdapter1* adapter = 0; - UINT n = 0; - while (dxgi_factory_->EnumAdapters1(n, &adapter) != DXGI_ERROR_NOT_FOUND) { - DXGI_ADAPTER_DESC1 desc; - adapter->GetDesc1(&desc); - adapter->Release(); - n++; - } - // Just go with the default for now. - adapter = 0; - - D3D_DRIVER_TYPE driver_type = - adapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE; - - UINT flags = 0; - // TODO(benvanik): runtime flag - flags |= D3D11_CREATE_DEVICE_DEBUG; - - // Feature level 11.0+ only. - D3D_FEATURE_LEVEL feature_levels[] = { - D3D_FEATURE_LEVEL_11_0, - }; - - // Create device. - D3D_FEATURE_LEVEL actual_feature_level; - ID3D11DeviceContext* immediate_context; - hr = D3D11CreateDevice( - adapter, - driver_type, - 0, // software driver HMODULE - flags, - feature_levels, - static_cast(poly::countof(feature_levels)), - D3D11_SDK_VERSION, - &device_, - &actual_feature_level, - &immediate_context); - if (adapter) { - adapter->Release(); - adapter = 0; - } - if (immediate_context) { - immediate_context->Release(); - immediate_context = 0; - } - if (FAILED(hr)) { - XELOGE("D3D11CreateDevice failed with %.8X", hr); - exit(1); - return; - } - - // Create the window. - // This will pump through the run-loop and and be where our swapping - // will take place. - assert_null(window_); - window_ = new D3D11Window(run_loop_, dxgi_factory_, device_); - if (window_->Initialize(L"Xenia D3D11", 1280, 720)) { - XELOGE("Failed to create D3D11Window"); - exit(1); - return; - } - emulator_->set_main_window(window_); - - // Listen for alt-enter/etc. - dxgi_factory_->MakeWindowAssociation(window_->handle(), 0); - - // Create the driver. - // This runs in the worker thread and builds command lines to present - // in the window. - assert_null(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"); - - auto time_since_last_swap = std::chrono::duration_cast( - std::chrono::high_resolution_clock::now() - last_swap_time_); - if (time_since_last_swap.count() > 1) { - // Force a swap when profiling. - if (Profiler::is_enabled()) { - window_->Swap(); - } - } -} - -void D3D11GraphicsSystem::Swap() { - // TODO(benvanik): remove this when commands are understood. - driver_->Resolve(); - - // Swap window. - // If we are set to vsync this will block. - window_->Swap(); - - last_swap_time_ = std::chrono::high_resolution_clock::now(); -} - -void __stdcall D3D11GraphicsSystem::VsyncCallback(D3D11GraphicsSystem* gs, - BOOLEAN) { - static bool thread_name_set = false; - if (!thread_name_set) { - thread_name_set = true; - Profiler::ThreadEnter("VsyncTimer"); - } - SCOPE_profile_cpu_f("gpu"); - - gs->MarkVblank(); - - // TODO(benvanik): we shouldn't need to do the dispatch here, but there's - // something wrong and the CP will block waiting for code that - // needs to be run in the interrupt. - gs->DispatchInterruptCallback(0); -} - -void D3D11GraphicsSystem::Shutdown() { - GraphicsSystem::Shutdown(); - - if (vsync_timer_) { - DeleteTimerQueueTimer(timer_queue_, vsync_timer_, NULL); - } - if (timer_queue_) { - DeleteTimerQueueEx(timer_queue_, NULL); - } - - SafeRelease(device_); - device_ = 0; - SafeRelease(dxgi_factory_); - dxgi_factory_ = 0; - delete window_; - window_ = 0; -} diff --git a/src/xenia/gpu/d3d11/d3d11_graphics_system.h b/src/xenia/gpu/d3d11/d3d11_graphics_system.h deleted file mode 100644 index 60f065bc3..000000000 --- a/src/xenia/gpu/d3d11/d3d11_graphics_system.h +++ /dev/null @@ -1,59 +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_GRAPHICS_SYSTEM_H_ -#define XENIA_GPU_D3D11_D3D11_GRAPHICS_SYSTEM_H_ - -#include -#include -#include - -namespace xe { -namespace gpu { -namespace d3d11 { - -class D3D11Window; - - -std::unique_ptr Create(Emulator* emulator); - - -class D3D11GraphicsSystem : public GraphicsSystem { -public: - D3D11GraphicsSystem(Emulator* emulator); - virtual ~D3D11GraphicsSystem(); - - virtual void Shutdown(); - - void Swap() override; - -protected: - virtual void Initialize(); - virtual void Pump(); - -private: - static void __stdcall VsyncCallback(D3D11GraphicsSystem* gs, BOOLEAN); - - IDXGIFactory1* dxgi_factory_; - ID3D11Device* device_; - D3D11Window* window_; - - HANDLE timer_queue_; - HANDLE vsync_timer_; - - std::chrono::high_resolution_clock::time_point last_swap_time_; -}; - - -} // namespace d3d11 -} // namespace gpu -} // namespace xe - - -#endif // XENIA_GPU_D3D11_D3D11_GRAPHICS_SYSTEM_H_ diff --git a/src/xenia/gpu/d3d11/d3d11_profiler_display.cc b/src/xenia/gpu/d3d11/d3d11_profiler_display.cc deleted file mode 100644 index 4c1672808..000000000 --- a/src/xenia/gpu/d3d11/d3d11_profiler_display.cc +++ /dev/null @@ -1,661 +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 - -#include - -#include -#include -#include - -#include - - -using namespace xe; -using namespace xe::gpu; -using namespace xe::gpu::d3d11; - - -namespace { -const uint8_t profiler_font[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x10,0x78,0x38,0x78,0x7c,0x7c,0x3c,0x44,0x38,0x04,0x44,0x40,0x44,0x44,0x38,0x78, - 0x38,0x78,0x38,0x7c,0x44,0x44,0x44,0x44,0x44,0x7c,0x00,0x00,0x40,0x00,0x04,0x00, - 0x18,0x00,0x40,0x10,0x08,0x40,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x10,0x38,0x7c,0x08,0x7c,0x1c,0x7c,0x38,0x38, - 0x10,0x28,0x28,0x10,0x00,0x20,0x10,0x08,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x04,0x00,0x20,0x38,0x38,0x70,0x00,0x1c,0x10,0x00,0x1c,0x10,0x70,0x30,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x28,0x44,0x44,0x44,0x40,0x40,0x40,0x44,0x10,0x04,0x48,0x40,0x6c,0x44,0x44,0x44, - 0x44,0x44,0x44,0x10,0x44,0x44,0x44,0x44,0x44,0x04,0x00,0x00,0x40,0x00,0x04,0x00, - 0x24,0x00,0x40,0x00,0x00,0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x30,0x44,0x04,0x18,0x40,0x20,0x04,0x44,0x44, - 0x10,0x28,0x28,0x3c,0x44,0x50,0x10,0x10,0x08,0x54,0x10,0x00,0x00,0x00,0x04,0x00, - 0x00,0x08,0x00,0x10,0x44,0x44,0x40,0x40,0x04,0x28,0x00,0x30,0x10,0x18,0x58,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x44,0x44,0x40,0x44,0x40,0x40,0x40,0x44,0x10,0x04,0x50,0x40,0x54,0x64,0x44,0x44, - 0x44,0x44,0x40,0x10,0x44,0x44,0x44,0x28,0x28,0x08,0x00,0x38,0x78,0x3c,0x3c,0x38, - 0x20,0x38,0x78,0x30,0x18,0x44,0x10,0x6c,0x78,0x38,0x78,0x3c,0x5c,0x3c,0x3c,0x44, - 0x44,0x44,0x44,0x44,0x7c,0x00,0x4c,0x10,0x04,0x08,0x28,0x78,0x40,0x08,0x44,0x44, - 0x10,0x00,0x7c,0x50,0x08,0x50,0x00,0x20,0x04,0x38,0x10,0x00,0x00,0x00,0x08,0x10, - 0x10,0x10,0x7c,0x08,0x08,0x54,0x40,0x20,0x04,0x44,0x00,0x30,0x10,0x18,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x44,0x78,0x40,0x44,0x78,0x78,0x40,0x7c,0x10,0x04,0x60,0x40,0x54,0x54,0x44,0x78, - 0x44,0x78,0x38,0x10,0x44,0x44,0x54,0x10,0x10,0x10,0x00,0x04,0x44,0x40,0x44,0x44, - 0x78,0x44,0x44,0x10,0x08,0x48,0x10,0x54,0x44,0x44,0x44,0x44,0x60,0x40,0x10,0x44, - 0x44,0x44,0x28,0x44,0x08,0x00,0x54,0x10,0x18,0x18,0x48,0x04,0x78,0x10,0x38,0x3c, - 0x10,0x00,0x28,0x38,0x10,0x20,0x00,0x20,0x04,0x10,0x7c,0x00,0x7c,0x00,0x10,0x00, - 0x00,0x20,0x00,0x04,0x10,0x5c,0x40,0x10,0x04,0x00,0x00,0x60,0x10,0x0c,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x7c,0x44,0x40,0x44,0x40,0x40,0x4c,0x44,0x10,0x04,0x50,0x40,0x44,0x4c,0x44,0x40, - 0x54,0x50,0x04,0x10,0x44,0x44,0x54,0x28,0x10,0x20,0x00,0x3c,0x44,0x40,0x44,0x7c, - 0x20,0x44,0x44,0x10,0x08,0x70,0x10,0x54,0x44,0x44,0x44,0x44,0x40,0x38,0x10,0x44, - 0x44,0x54,0x10,0x44,0x10,0x00,0x64,0x10,0x20,0x04,0x7c,0x04,0x44,0x20,0x44,0x04, - 0x10,0x00,0x7c,0x14,0x20,0x54,0x00,0x20,0x04,0x38,0x10,0x10,0x00,0x00,0x20,0x10, - 0x10,0x10,0x7c,0x08,0x10,0x58,0x40,0x08,0x04,0x00,0x00,0x30,0x10,0x18,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x44,0x44,0x44,0x44,0x40,0x40,0x44,0x44,0x10,0x44,0x48,0x40,0x44,0x44,0x44,0x40, - 0x48,0x48,0x44,0x10,0x44,0x28,0x6c,0x44,0x10,0x40,0x00,0x44,0x44,0x40,0x44,0x40, - 0x20,0x3c,0x44,0x10,0x08,0x48,0x10,0x54,0x44,0x44,0x44,0x44,0x40,0x04,0x12,0x4c, - 0x28,0x54,0x28,0x3c,0x20,0x00,0x44,0x10,0x40,0x44,0x08,0x44,0x44,0x20,0x44,0x08, - 0x00,0x00,0x28,0x78,0x44,0x48,0x00,0x10,0x08,0x54,0x10,0x10,0x00,0x00,0x40,0x00, - 0x10,0x08,0x00,0x10,0x00,0x40,0x40,0x04,0x04,0x00,0x00,0x30,0x10,0x18,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x44,0x78,0x38,0x78,0x7c,0x40,0x3c,0x44,0x38,0x38,0x44,0x7c,0x44,0x44,0x38,0x40, - 0x34,0x44,0x38,0x10,0x38,0x10,0x44,0x44,0x10,0x7c,0x00,0x3c,0x78,0x3c,0x3c,0x3c, - 0x20,0x04,0x44,0x38,0x48,0x44,0x38,0x44,0x44,0x38,0x78,0x3c,0x40,0x78,0x0c,0x34, - 0x10,0x6c,0x44,0x04,0x7c,0x00,0x38,0x38,0x7c,0x38,0x08,0x38,0x38,0x20,0x38,0x70, - 0x10,0x00,0x28,0x10,0x00,0x34,0x00,0x08,0x10,0x10,0x00,0x20,0x00,0x10,0x00,0x00, - 0x20,0x04,0x00,0x20,0x10,0x3c,0x70,0x00,0x1c,0x00,0x7c,0x1c,0x10,0x70,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x38,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x40,0x04,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -}; - -const char* shader_code = " \ -cbuffer MatrixBuffer {\n \ - float4x4 projection_matrix;\n \ -};\n \ -Texture2D texture0;\n \ -SamplerState sampler0;\n \ -struct Vertex {\n \ - float2 position : POSITION0;\n \ - float2 tex : TEXCOORD0;\n \ - float4 color : COLOR0;\n \ -};\n \ -struct Pixel {\n \ - float4 position : SV_POSITION;\n \ - float2 tex : TEXCOORD0;\n \ - float4 color : COLOR0;\n \ -};\n \ -Pixel vs(Vertex v) {\n \ - Pixel p;\n \ - p.position = float4(mul(float4(v.position, 0.0f, 1.0f), projection_matrix).xy - float2(1.0f, -1.0f), 0.0f, 1.0f);\n \ - p.tex = v.tex;\n \ - p.color = v.color;\n \ - return p;\n \ -}\n \ -float4 ps(Pixel p) : SV_TARGET {\n \ - if (p.tex.x > 1.0f) {\n \ - return float4(p.color.rgb, 0.5f);\n \ - } else {\n \ - float4 sample = texture0.Sample(sampler0, p.tex);\n \ - if(sample.w < 0.5f) {\n \ - discard;\n \ - }\n \ - return p.color * sample;\n \ - }\n \ -}\n"; - -} // namespace - - -D3D11ProfilerDisplay::D3D11ProfilerDisplay(D3D11Window* window) : window_(window) { - draw_state_ = { 0 }; - if (!SetupState() || - !SetupShaders() || - !SetupFont()) { - // Hrm. - assert_always(); - } - - // Pass through mouse events. - window->mouse_down.AddListener([](xe::ui::MouseEvent& e) { - Profiler::OnMouseDown( - e.button() == xe::ui::MouseEvent::MOUSE_BUTTON_LEFT, - e.button() == xe::ui::MouseEvent::MOUSE_BUTTON_RIGHT); - }); - window->mouse_up.AddListener([](xe::ui::MouseEvent& e) { - Profiler::OnMouseUp(); - }); - window->mouse_move.AddListener([](xe::ui::MouseEvent& e) { - Profiler::OnMouseMove(e.x(), e.y()); - }); - window->mouse_wheel.AddListener([](xe::ui::MouseEvent& e) { - Profiler::OnMouseWheel(e.x(), e.y(), -e.dy()); - }); - - // Watch for toggle/mode keys and such. - window->key_down.AddListener([](xe::ui::KeyEvent& e) { - Profiler::OnKeyDown(e.key_code()); - }); - window->key_up.AddListener([](xe::ui::KeyEvent& e) { - Profiler::OnKeyUp(e.key_code()); - }); -} - -bool D3D11ProfilerDisplay::SetupState() { - HRESULT hr; - auto device = window_->device(); - - D3D11_BLEND_DESC blend_desc = {0}; - blend_desc.RenderTarget[0].BlendEnable = true; - blend_desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - blend_desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - blend_desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - blend_desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ZERO; - blend_desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - blend_desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - blend_desc.RenderTarget[0].RenderTargetWriteMask = 0x0F; - hr = device->CreateBlendState(&blend_desc, &blend_state_); - assert_true(SUCCEEDED(hr)); - - D3D11_DEPTH_STENCIL_DESC depth_stencil_desc = {0}; - depth_stencil_desc.DepthEnable = false; - depth_stencil_desc.StencilEnable = false; - depth_stencil_desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; - hr = device->CreateDepthStencilState(&depth_stencil_desc, &depth_stencil_state_); - assert_true(SUCCEEDED(hr)); - - return true; -} - -bool D3D11ProfilerDisplay::SetupShaders() { - HRESULT hr; - auto device = window_->device(); - - ID3DBlob* vs_code_blob = nullptr; - ID3DBlob* vs_errors = nullptr; - hr = D3DCompile( - shader_code, strlen(shader_code), - "D3D11ProfilerDisplay.vs", - nullptr, - nullptr, - "vs", - "vs_5_0", - D3DCOMPILE_ENABLE_STRICTNESS, - 0, - &vs_code_blob, - &vs_errors); - if (FAILED(hr)) { - XELOGE("Failed to compile profiler vs: %s", - reinterpret_cast(vs_errors->GetBufferPointer())); - return false; - } - hr = device->CreateVertexShader(vs_code_blob->GetBufferPointer(), - vs_code_blob->GetBufferSize(), - nullptr, - &vertex_shader_); - if (FAILED(hr)) { - XELOGE("Failed to create profiler vs"); - return false; - } - ID3DBlob* ps_code_blob = nullptr; - ID3DBlob* ps_errors = nullptr; - hr = D3DCompile( - shader_code, strlen(shader_code), - "D3D11ProfilerDisplay.ps", - nullptr, - nullptr, - "ps", - "ps_5_0", - D3DCOMPILE_ENABLE_STRICTNESS, - 0, - &ps_code_blob, - &ps_errors); - if (FAILED(hr)) { - XELOGE("Failed to compile profiler ps: %s", - reinterpret_cast(ps_errors->GetBufferPointer())); - return false; - } - hr = device->CreatePixelShader(ps_code_blob->GetBufferPointer(), - ps_code_blob->GetBufferSize(), - nullptr, - &pixel_shader_); - if (FAILED(hr)) { - XELOGE("Failed to create profiler ps"); - return false; - } - - D3D11_BUFFER_DESC buffer_desc = { 0 }; - buffer_desc.Usage = D3D11_USAGE_DYNAMIC; - buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - buffer_desc.ByteWidth = sizeof(float) * 16; - hr = device->CreateBuffer(&buffer_desc, nullptr, &shader_constants_); - if (FAILED(hr)) { - XELOGE("Failed to create profiler constant buffer"); - return false; - } - - D3D11_INPUT_ELEMENT_DESC element_descs[] = { - { - "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, - D3D11_INPUT_PER_VERTEX_DATA, 0, - }, - { - "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, - D3D11_INPUT_PER_VERTEX_DATA, 0, - }, - { - "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, D3D11_APPEND_ALIGNED_ELEMENT, - D3D11_INPUT_PER_VERTEX_DATA, 0, - }, - }; - hr = device->CreateInputLayout( - element_descs, (UINT)poly::countof(element_descs), - vs_code_blob->GetBufferPointer(), vs_code_blob->GetBufferSize(), - &shader_layout_); - if (FAILED(hr)) { - XELOGE("Failed to create profiler input layout"); - return false; - } - - buffer_desc.Usage = D3D11_USAGE_DYNAMIC; - buffer_desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - buffer_desc.ByteWidth = sizeof(draw_state_.vertex_buffer); - hr = device->CreateBuffer(&buffer_desc, nullptr, &vertex_buffer_); - if (FAILED(hr)) { - XELOGE("Failed to create profiler vertex buffer"); - return false; - } - - return true; -} - -bool D3D11ProfilerDisplay::SetupFont() { - HRESULT hr; - auto device = window_->device(); - - // Setup font lookup table. - for (uint32_t i = 0; i < poly::countof(font_description_.char_offsets); ++i) { - font_description_.char_offsets[i] = 206; - } - for (uint32_t i = 'A'; i <= 'Z'; ++i) { - font_description_.char_offsets[i] = (i-'A')*8+1; - } - for (uint32_t i = 'a'; i <= 'z'; ++i) { - font_description_.char_offsets[i] = (i-'a')*8+217; - } - for (uint32_t i = '0'; i <= '9'; ++i) { - font_description_.char_offsets[i] = (i-'0')*8+433; - } - for (uint32_t i = '!'; i <= '/'; ++i) { - font_description_.char_offsets[i] = (i-'!')*8+513; - } - for (uint32_t i = ':'; i <= '@'; ++i) { - font_description_.char_offsets[i] = (i-':')*8+625+8; - } - for (uint32_t i = '['; i <= '_'; ++i) { - font_description_.char_offsets[i] = (i-'[')*8+681+8; - } - for (uint32_t i = '{'; i <= '~'; ++i) { - font_description_.char_offsets[i] = (i-'{')*8+721+8; - } - - // Unpack font bitmap into an RGBA texture. - const int FONT_TEX_X = 1024; - const int FONT_TEX_Y = 9; - const int UNPACKED_SIZE = FONT_TEX_X * FONT_TEX_Y * 4; - uint32_t unpacked[UNPACKED_SIZE]; - int idx = 0; - int end = FONT_TEX_X * FONT_TEX_Y / 8; - for (int i = 0; i < end; i++) { - uint8_t b = profiler_font[i]; - for (int j = 0; j < 8; ++j) { - unpacked[idx++] = b & 0x80 ? 0xFFFFFFFFu : 0; - b <<= 1; - } - } - - D3D11_TEXTURE2D_DESC texture_desc = { 0 }; - texture_desc.Width = FONT_TEX_X; - texture_desc.Height = FONT_TEX_Y; - texture_desc.MipLevels = 1; - texture_desc.ArraySize = 1; - texture_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - texture_desc.SampleDesc.Count = 1; - texture_desc.SampleDesc.Quality = 0; - texture_desc.Usage = D3D11_USAGE_IMMUTABLE; - texture_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - texture_desc.CPUAccessFlags = 0; - texture_desc.MiscFlags = 0; - D3D11_SUBRESOURCE_DATA initial_data = { 0 }; - initial_data.pSysMem = unpacked; - initial_data.SysMemPitch = FONT_TEX_X * 4; - initial_data.SysMemSlicePitch = 0; - ID3D11Texture2D* font_texture = nullptr; - hr = device->CreateTexture2D(&texture_desc, &initial_data, &font_texture); - if (FAILED(hr)) { - XELOGE("Unable to create profiler font texture"); - return false; - } - - D3D11_SHADER_RESOURCE_VIEW_DESC texture_view_desc = {}; - texture_view_desc.Format = texture_desc.Format; - texture_view_desc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D; - texture_view_desc.Texture2D.MipLevels = 1; - texture_view_desc.Texture2D.MostDetailedMip = 0; - hr = device->CreateShaderResourceView( - font_texture, &texture_view_desc, &font_texture_view_); - SafeRelease(font_texture); - if (FAILED(hr)) { - XELOGE("Unable to create profiler font texture view"); - return false; - } - - D3D11_SAMPLER_DESC sampler_desc = {}; - sampler_desc.Filter = D3D11_ENCODE_BASIC_FILTER( - D3D11_FILTER_TYPE_POINT, D3D11_FILTER_TYPE_POINT, - D3D11_FILTER_TYPE_POINT, false); - sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; - sampler_desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; - sampler_desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - sampler_desc.MipLODBias; - sampler_desc.MaxAnisotropy = 1; - sampler_desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; - sampler_desc.BorderColor[0]; - sampler_desc.BorderColor[1]; - sampler_desc.BorderColor[2]; - sampler_desc.BorderColor[3]; - sampler_desc.MinLOD; - sampler_desc.MaxLOD; - hr = device->CreateSamplerState( - &sampler_desc, &font_sampler_state_); - if (FAILED(hr)) { - PFATAL("D3D11: unable to create invalid sampler state"); - return false; - } - - return true; -} - -D3D11ProfilerDisplay::~D3D11ProfilerDisplay() { - SafeRelease(blend_state_); - SafeRelease(depth_stencil_state_); - SafeRelease(vertex_shader_); - SafeRelease(pixel_shader_); - SafeRelease(shader_constants_); - SafeRelease(shader_layout_); - SafeRelease(font_texture_view_); - SafeRelease(font_sampler_state_); - SafeRelease(vertex_buffer_); -} - -uint32_t D3D11ProfilerDisplay::width() const { - return window_->width(); -} - -uint32_t D3D11ProfilerDisplay::height() const { - return window_->height(); -} - -void D3D11ProfilerDisplay::Begin() { - auto context = window_->context(); - - D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0.0f; - viewport.TopLeftY = 0.0f; - viewport.Width = static_cast(width()); - viewport.Height = static_cast(height()); - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - context->RSSetViewports(1, &viewport); - - // Setup projection matrix. - float left = viewport.TopLeftX; - float right = viewport.TopLeftX + viewport.Width; - float bottom = viewport.TopLeftY + viewport.Height; - float top = viewport.TopLeftY; - float z_near = viewport.MinDepth; - float z_far = viewport.MaxDepth; - float projection[16] = { 0 }; - projection[0] = 2.0f / (right - left); - projection[5] = 2.0f / (top - bottom); - projection[10] = -2.0f / (z_far - z_near); - projection[12] = -(right + left) / (right - left); - projection[13] = -(top + bottom) / (top - bottom); - projection[14] = -(z_far + z_near) / (z_far - z_near); - projection[15] = 1.0f; - D3D11_MAPPED_SUBRESOURCE res; - context->Map(shader_constants_, 0, D3D11_MAP_WRITE_DISCARD, 0, &res); - memcpy(res.pData, projection, sizeof(projection)); - context->Unmap(shader_constants_, 0); - - // Setup state. - context->OMSetBlendState(blend_state_, { 0 }, 0xFFFFFFFF); - context->OMSetDepthStencilState(depth_stencil_state_, 0); - - // Bind shaders. - context->GSSetShader(nullptr, nullptr, 0); - context->VSSetShader(vertex_shader_, nullptr, 0); - context->VSSetConstantBuffers(0, 1, &shader_constants_); - context->PSSetShader(pixel_shader_, nullptr, 0); - context->PSSetConstantBuffers(0, 1, &shader_constants_); - ID3D11SamplerState* ps_samplers[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = { - font_sampler_state_, - nullptr, - }; - context->PSSetSamplers(0, static_cast(poly::countof(ps_samplers)), - ps_samplers); - ID3D11ShaderResourceView* - ps_resources[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT] = { - font_texture_view_, nullptr, - }; - context->PSSetShaderResources( - 0, static_cast(poly::countof(ps_resources)), ps_resources); - context->IASetInputLayout(shader_layout_); -} - -void D3D11ProfilerDisplay::End() { - Flush(); -} - -D3D11ProfilerDisplay::Vertex* D3D11ProfilerDisplay::AllocateVertices( - D3D_PRIMITIVE_TOPOLOGY primitive, size_t count) { - if (draw_state_.vertex_index + count > - poly::countof(draw_state_.vertex_buffer)) { - Flush(); - } - assert_true(draw_state_.vertex_index + count <= - poly::countof(draw_state_.vertex_buffer)); - - size_t head = draw_state_.vertex_index; - draw_state_.vertex_index += count; - - if (draw_state_.command_index && - draw_state_.commands[draw_state_.command_index - 1].primitive == - primitive) { - draw_state_.commands[draw_state_.command_index - 1].vertex_count += count; - } else { - assert_true(draw_state_.command_index < - poly::countof(draw_state_.commands)); - draw_state_.commands[draw_state_.command_index].primitive = primitive; - draw_state_.commands[draw_state_.command_index].vertex_count = count; - ++draw_state_.command_index; - } - return &draw_state_.vertex_buffer[head]; -} - -void D3D11ProfilerDisplay::Flush() { - auto context = window_->context(); - if (!draw_state_.vertex_index) { - return; - } - - D3D11_MAPPED_SUBRESOURCE res; - context->Map(vertex_buffer_, 0, D3D11_MAP_WRITE_DISCARD, 0, &res); - memcpy(res.pData, draw_state_.vertex_buffer, sizeof(Vertex) * draw_state_.vertex_index); - context->Unmap(vertex_buffer_, 0); - - uint32_t stride = 20; - uint32_t offset = 0; - context->IASetVertexBuffers(0, 1, &vertex_buffer_, &stride, &offset); - - size_t vertex_index = 0; - for (int i = 0; i < draw_state_.command_index; ++i) { - size_t count = draw_state_.commands[i].vertex_count; - context->IASetPrimitiveTopology(draw_state_.commands[i].primitive); - context->Draw((UINT)count, (UINT)vertex_index); - vertex_index += count; - } - - draw_state_.vertex_index = 0; - draw_state_.command_index = 0; -} - -#define Q0(d, member, v) d[0].member = v -#define Q1(d, member, v) d[1].member = v; d[3].member = v -#define Q2(d, member, v) d[4].member = v -#define Q3(d, member, v) d[2].member = v; d[5].member = v - -void D3D11ProfilerDisplay::DrawBox( - int x, int y, int x1, int y1, uint32_t color, BoxType type) { - Vertex* v = AllocateVertices(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, 6); - uint32_t color0; - uint32_t color1; - if (type == BOX_TYPE_FLAT) { - color0 = 0xFF000000 | - ((color & 0xFF) << 16) | - (color & 0xFF00FF00) | - ((color >> 16) & 0xFF); - color1 = color0; - } else { - uint32_t r = 0xFF & (color >> 16); - uint32_t g = 0xFF & (color >> 8); - uint32_t b = 0xFF & color; - uint32_t max_c = std::max(std::max(std::max(r, g), b), 30u); - uint32_t min_c = std::min(std::min(std::min(r, g), b), 180u); - uint32_t r0 = 0xFF & ((r + max_c)/2); - uint32_t g0 = 0xFF & ((g + max_c)/2); - uint32_t b0 = 0xFF & ((b + max_c)/2); - uint32_t r1 = 0xFF & ((r + min_c) / 2); - uint32_t g1 = 0xFF & ((g + min_c) / 2); - uint32_t b1 = 0xFF & ((b + min_c) / 2); - color0 = r0 | (g0 << 8) | (b0 << 16) | (0xFF000000 & color); - color1 = r1 | (g1 << 8) | (b1 << 16) | (0xFF000000 & color); - } - Q0(v, x, (float)x); - Q0(v, y, (float)y); - Q0(v, color, color0); - Q0(v, u, 2.0f); - Q0(v, v, 2.0f); - Q1(v, x, (float)x1); - Q1(v, y, (float)y); - Q1(v, color, color0); - Q1(v, u, 3.0f); - Q1(v, v, 2.0f); - Q2(v, x, (float)x1); - Q2(v, y, (float)y1); - Q2(v, color, color1); - Q2(v, u, 3.0f); - Q2(v, v, 3.0f); - Q3(v, x, (float)x); - Q3(v, y, (float)y1); - Q3(v, color, color1); - Q3(v, u, 2.0f); - Q3(v, v, 3.0f); -} - -void D3D11ProfilerDisplay::DrawLine2D( - uint32_t count, float* vertices, uint32_t color) { - if (!count || !vertices) { - return; - } - color = 0xFF000000 | - ((color & 0xFF) << 16) | - (color & 0xFF00FF00) | - ((color >> 16) & 0xFF); - Vertex* v = AllocateVertices(D3D11_PRIMITIVE_TOPOLOGY_LINELIST, 2 * (count - 1)); - for (uint32_t i = 0; i < count - 1; ++i) { - v[0].x = vertices[i * 2]; - v[0].y = vertices[i * 2 + 1]; - v[0].color = color; - v[0].u = 2.0f; - v[0].v = 2.0f; - v[1].x = vertices[(i + 1) * 2]; - v[1].y = vertices[(i + 1) * 2 + 1] ; - v[1].color = color; - v[1].u = 2.0f; - v[1].v = 2.0f; - v += 2; - } -} - -void D3D11ProfilerDisplay::DrawText( - int x, int y, uint32_t color, const char* text, size_t text_length) { - const float offset_u = 5.0f / 1024.0f; - float fx = (float)x; - float fy = (float)y; - float fy2 = fy + (MICROPROFILE_TEXT_HEIGHT + 1); - color = 0xFF000000 | - ((color & 0xFF) << 16) | - (color & 0xFF00FF00) | - ((color >> 16) & 0xFF); - Vertex* v = AllocateVertices(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, 6 * text_length); - const char* s = text; - for (uint32_t j = 0; j < text_length; ++j) { - int16_t nOffset = font_description_.char_offsets[(int)*s++]; - float fOffset = nOffset / 1024.f; - Q0(v, x, fx); - Q0(v, y, fy); - Q0(v, color, color); - Q0(v, u, fOffset); - Q0(v, v, 0.0f); - Q1(v, x, fx + MICROPROFILE_TEXT_WIDTH); - Q1(v, y, fy); - Q1(v, color, color); - Q1(v, u, fOffset + offset_u); - Q1(v, v, 0.0f); - Q2(v, x, fx + MICROPROFILE_TEXT_WIDTH); - Q2(v, y, fy2); - Q2(v, color, color); - Q2(v, u, fOffset + offset_u); - Q2(v, v, 1.0f); - Q3(v, x, fx); - Q3(v, y, fy2); - Q3(v, color, color); - Q3(v, u, fOffset); - Q3(v, v, 1.0f); - fx += MICROPROFILE_TEXT_WIDTH + 1; - v += 6; - } -} diff --git a/src/xenia/gpu/d3d11/d3d11_profiler_display.h b/src/xenia/gpu/d3d11/d3d11_profiler_display.h deleted file mode 100644 index 5162f9dd1..000000000 --- a/src/xenia/gpu/d3d11/d3d11_profiler_display.h +++ /dev/null @@ -1,80 +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_PROFILER_DISPLAY_H_ -#define XENIA_GPU_D3D11_D3D11_PROFILER_DISPLAY_H_ - -#include -#include - -namespace xe { -namespace gpu { -namespace d3d11 { - -class D3D11Window; - -class D3D11ProfilerDisplay : public ProfilerDisplay { -public: - D3D11ProfilerDisplay(D3D11Window* window); - virtual ~D3D11ProfilerDisplay(); - - uint32_t width() const override; - uint32_t height() const override; - - // TODO(benvanik): GPU timestamping. - - void Begin() override; - void End() override; - void DrawBox(int x, int y, int x1, int y1, uint32_t color, BoxType type) override; - void DrawLine2D(uint32_t count, float* vertices, uint32_t color) override; - void DrawText(int x, int y, uint32_t color, const char* text, size_t text_length) override; - -private: - bool SetupState(); - bool SetupShaders(); - bool SetupFont(); - - struct Vertex { - float x, y; - float u, v; - uint32_t color; - }; - struct { - size_t vertex_index; - Vertex vertex_buffer[16 << 10]; - struct { - D3D11_PRIMITIVE_TOPOLOGY primitive; - size_t vertex_count; - } commands[32]; - size_t command_index; - } draw_state_; - Vertex* AllocateVertices(D3D_PRIMITIVE_TOPOLOGY primitive, size_t count); - void Flush(); - - D3D11Window* window_; - ID3D11BlendState* blend_state_; - ID3D11DepthStencilState* depth_stencil_state_; - ID3D11VertexShader* vertex_shader_; - ID3D11PixelShader* pixel_shader_; - ID3D11Buffer* shader_constants_; - ID3D11InputLayout* shader_layout_; - ID3D11ShaderResourceView* font_texture_view_; - ID3D11SamplerState* font_sampler_state_; - ID3D11Buffer* vertex_buffer_; - - struct { - uint16_t char_offsets[256]; - } font_description_; -}; - -} // namespace d3d11 -} // namespace gpu -} // namespace xe - -#endif // XENIA_GPU_D3D11_D3D11_PROFILER_DISPLAY_H_ diff --git a/src/xenia/gpu/d3d11/d3d11_resource_cache.cc b/src/xenia/gpu/d3d11/d3d11_resource_cache.cc deleted file mode 100644 index aaab4148e..000000000 --- a/src/xenia/gpu/d3d11/d3d11_resource_cache.cc +++ /dev/null @@ -1,71 +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 - -#include -#include -#include -#include -#include - - -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() { - SafeRelease(device_); - SafeRelease(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); -} diff --git a/src/xenia/gpu/d3d11/d3d11_resource_cache.h b/src/xenia/gpu/d3d11/d3d11_resource_cache.h deleted file mode 100644 index 0ae6092bf..000000000 --- a/src/xenia/gpu/d3d11/d3d11_resource_cache.h +++ /dev/null @@ -1,58 +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_RESOURCE_CACHE_H_ -#define XENIA_GPU_D3D11_D3D11_RESOURCE_CACHE_H_ - -#include -#include -#include - -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_ diff --git a/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.cc b/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.cc deleted file mode 100644 index 3572f5718..000000000 --- a/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.cc +++ /dev/null @@ -1,105 +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 - -#include - - -using namespace std; -using namespace xe; -using namespace xe::gpu; -using namespace xe::gpu::d3d11; -using namespace xe::gpu::xenos; - - -D3D11SamplerStateResource::D3D11SamplerStateResource( - D3D11ResourceCache* resource_cache, const Info& info) - : SamplerStateResource(info), - resource_cache_(resource_cache), - handle_(nullptr) { -} - -D3D11SamplerStateResource::~D3D11SamplerStateResource() { - SafeRelease(handle_); -} - -int D3D11SamplerStateResource::Prepare() { - if (handle_) { - return 0; - } - - D3D11_SAMPLER_DESC sampler_desc = {}; - // MIN, MAG, MIP - static const D3D11_FILTER filter_matrix[2][2][3] = { - { - // min = POINT - { - // mag = POINT - D3D11_FILTER_MIN_MAG_MIP_POINT, - D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR, - D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR, // basemap? - }, - { - // mag = LINEAR - D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT, - D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR, - D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR, // basemap? - }, - }, - { - // min = LINEAR - { - // mag = POINT - D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT, - D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR, - D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR, // basemap? - }, - { - // mag = LINEAR - D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT, - D3D11_FILTER_MIN_MAG_MIP_LINEAR, - D3D11_FILTER_MIN_MAG_MIP_LINEAR, // basemap? - }, - }, - }; - 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, - D3D11_TEXTURE_ADDRESS_CLAMP, // ? - D3D11_TEXTURE_ADDRESS_MIRROR_ONCE, // ? - D3D11_TEXTURE_ADDRESS_CLAMP, // ? - D3D11_TEXTURE_ADDRESS_MIRROR_ONCE, // ? - D3D11_TEXTURE_ADDRESS_BORDER, // ? - D3D11_TEXTURE_ADDRESS_MIRROR, // ? - }; - 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; - sampler_desc.BorderColor[0]; - sampler_desc.BorderColor[1]; - sampler_desc.BorderColor[2]; - sampler_desc.BorderColor[3]; - sampler_desc.MinLOD; - sampler_desc.MaxLOD; - - HRESULT hr = resource_cache_->device()->CreateSamplerState( - &sampler_desc, &handle_); - if (FAILED(hr)) { - XELOGE("D3D11: unable to create sampler state"); - return 1; - } - - return 0; -} diff --git a/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.h b/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.h deleted file mode 100644 index 35447dbc9..000000000 --- a/src/xenia/gpu/d3d11/d3d11_sampler_state_resource.h +++ /dev/null @@ -1,47 +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_SAMPLER_STATE_RESOURCE_H_ -#define XENIA_GPU_D3D11_D3D11_SAMPLER_STATE_RESOURCE_H_ - -#include -#include -#include -#include - - -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_ diff --git a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc b/src/xenia/gpu/d3d11/d3d11_shader_resource.cc deleted file mode 100644 index e352936a7..000000000 --- a/src/xenia/gpu/d3d11/d3d11_shader_resource.cc +++ /dev/null @@ -1,375 +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 - -#include -#include -#include -#include -#include -#include -#include - -#include - -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 = hash64(disasm_source, strlen(disasm_source)); // ? - char file_name[poly::max_path]; - snprintf(file_name, poly::countof(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); - } - SafeRelease(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) { - memset(geometry_shaders_, 0, sizeof(geometry_shaders_)); -} - -D3D11VertexShaderResource::~D3D11VertexShaderResource() { - SafeRelease(handle_); - SafeRelease(input_layout_); - for (int i = 0; i < poly::countof(geometry_shaders_); ++i) { - delete geometry_shaders_[i]; - } - 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_ = strdup(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 = malloc(byte_code_length); - memcpy(byte_code, shader_blob->GetBufferPointer(), byte_code_length); - SafeRelease(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"); - free(byte_code); - return 1; - } - - // Create input layout. - ret = CreateInputLayout(byte_code, byte_code_length); - 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*)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: - assert_always(); - 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: - assert_always(); - 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() { - SafeRelease(handle_); - 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_ = strdup(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 = malloc(byte_code_length); - memcpy(byte_code, shader_blob->GetBufferPointer(), byte_code_length); - SafeRelease(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"); - free(byte_code); - return 1; - } - - free(byte_code); - is_prepared_ = true; - return 0; -} diff --git a/src/xenia/gpu/d3d11/d3d11_shader_resource.h b/src/xenia/gpu/d3d11/d3d11_shader_resource.h deleted file mode 100644 index 5c0da8242..000000000 --- a/src/xenia/gpu/d3d11/d3d11_shader_resource.h +++ /dev/null @@ -1,91 +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_SHADER_RESOURCE_H_ -#define XENIA_GPU_D3D11_D3D11_SHADER_RESOURCE_H_ - -#include -#include - -#include - - -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_ diff --git a/src/xenia/gpu/d3d11/d3d11_shader_translator.cc b/src/xenia/gpu/d3d11/d3d11_shader_translator.cc deleted file mode 100644 index e69d6a316..000000000 --- a/src/xenia/gpu/d3d11/d3d11_shader_translator.cc +++ /dev/null @@ -1,1659 +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 - -#include - -#include -#include -#include -#include - - -using namespace xe; -using namespace xe::gpu; -using namespace xe::gpu::d3d11; -using namespace xe::gpu::xenos; - - -namespace { - -const char* GetFormatTypeName(const VertexBufferResource::DeclElement& el) { - switch (el.format) { - case FMT_32: - return el.is_signed ? "int" : "uint"; - case FMT_32_FLOAT: - return "float"; - case FMT_16_16: - case FMT_32_32: - if (el.is_normalized) { - return el.is_signed ? "snorm float2" : "unorm float2"; - } else { - return el.is_signed ? "int2" : "uint2"; - } - case FMT_16_16_FLOAT: - case FMT_32_32_FLOAT: - return "float2"; - case FMT_10_11_11: - case FMT_11_11_10: - return "int3"; // ? - case FMT_32_32_32_FLOAT: - return "float3"; - case FMT_8_8_8_8: - case FMT_2_10_10_10: - case FMT_16_16_16_16: - case FMT_32_32_32_32: - if (el.is_normalized) { - return el.is_signed ? "snorm float4" : "unorm float4"; - } else { - return el.is_signed ? "int4" : "uint4"; - } - case FMT_16_16_16_16_FLOAT: - case FMT_32_32_32_32_FLOAT: - return "float4"; - default: - XELOGE("Unknown vertex format: %d", el.format); - assert_always(); - return "float4"; - } -} - -} // anonymous namespace - -D3D11ShaderTranslator::D3D11ShaderTranslator() - : capacity_(kCapacity), offset_(0) { - buffer_[0] = 0; -} - -int D3D11ShaderTranslator::TranslateVertexShader( - VertexShaderResource* vertex_shader, - const xe_gpu_program_cntl_t& program_cntl) { - SCOPE_profile_cpu_f("gpu"); - - type_ = XE_GPU_SHADER_TYPE_VERTEX; - tex_fetch_index_ = 0; - dwords_ = vertex_shader->dwords(); - - // Add constants buffers. - // We could optimize this by only including used buffers, but the compiler - // seems to do a good job of doing this for us. - // It also does read detection, so c[512] can end up c[4] in the asm - - // instead of doing this optimization ourselves we could maybe just query - // this from the compiler. - append( - "cbuffer float_consts : register(b0) {\n" - " float4 c[512];\n" - "};\n"); - // TODO(benvanik): add bool/loop constants. - - AppendTextureHeader(vertex_shader->sampler_inputs()); - - // Transform utilities. We adjust the output position in various ways - // as we can't do this via D3D11 APIs. - append( - "cbuffer vs_consts : register(b3) {\n" - " float4 window;\n" // x,y,w,h - " float4 viewport_z_enable;\n" // min,(max - min),?,enabled - " float4 viewport_size;\n" // x,y,w,h - "};" - "float4 applyViewport(float4 pos) {\n" - " if (viewport_z_enable.w) {\n" - //" pos.x = (pos.x + 1) * viewport_size.z * 0.5 + viewport_size.x;\n" - //" pos.y = (1 - pos.y) * viewport_size.w * 0.5 + viewport_size.y;\n" - //" pos.z = viewport_z_enable.x + pos.z * viewport_z_enable.y;\n" - // w? - " } else {\n" - " pos.xy = pos.xy / float2(window.z / 2.0, -window.w / 2.0) + float2(-1.0, 1.0);\n" - " pos.zw = float2(0.0, 1.0);\n" - " }\n" - " pos.xy += window.xy;\n" - " return pos;\n" - "}\n"); - - // Add vertex shader input. - append( - "struct VS_INPUT {\n"); - uint32_t el_index = 0; - const auto& buffer_inputs = vertex_shader->buffer_inputs(); - for (uint32_t n = 0; n < buffer_inputs.count; n++) { - const auto& input = buffer_inputs.descs[n]; - for (uint32_t m = 0; m < input.info.element_count; m++) { - const auto& el = input.info.elements[m]; - const char* type_name = GetFormatTypeName(el); - const auto& fetch = el.vtx_fetch; - uint32_t fetch_slot = fetch.const_index * 3 + fetch.const_index_sel; - append( - " %s vf%u_%d : XE_VF%u;\n", - type_name, fetch_slot, fetch.offset, el_index); - el_index++; - } - } - append( - "};\n"); - - // Add vertex shader output (pixel shader input). - const auto& alloc_counts = vertex_shader->alloc_counts(); - append( - "struct VS_OUTPUT {\n"); - if (alloc_counts.positions) { - assert_true(alloc_counts.positions == 1); - append( - " float4 oPos : SV_POSITION;\n"); - } - if (alloc_counts.params) { - append( - " float4 o[%d] : XE_O;\n", - kMaxInterpolators); - } - if (alloc_counts.point_size) { - append( - " float4 oPointSize : PSIZE;\n"); - } - append( - "};\n"); - - // Vertex shader main() header. - append( - "VS_OUTPUT main(VS_INPUT i) {\n" - " VS_OUTPUT o;\n"); - - // Always write position, as some shaders seem to only write certain values. - if (alloc_counts.positions) { - append( - " o.oPos = float4(0.0, 0.0, 0.0, 1.0);\n"); - } - if (alloc_counts.point_size) { - append( - " o.oPointSize = float4(1.0, 0.0, 0.0, 0.0);\n"); - } - - // TODO(benvanik): remove this, if possible (though the compiler may be smart - // enough to do it for us). - if (alloc_counts.params) { - for (uint32_t n = 0; n < kMaxInterpolators; n++) { - append( - " o.o[%d] = float4(0.0, 0.0, 0.0, 0.0);\n", n); - } - } - - // Add temporaries for any registers we may use. - uint32_t temp_regs = program_cntl.vs_regs + program_cntl.ps_regs; - for (uint32_t n = 0; n <= temp_regs; n++) { - append( - " float4 r%d = c[%d];\n", n, n); - } - append(" float4 t;\n"); - - // Execute blocks. - const auto& execs = vertex_shader->execs(); - for (auto it = execs.begin(); it != execs.end(); ++it) { - const instr_cf_exec_t& cf = *it; - // TODO(benvanik): figure out how sequences/jmps/loops/etc work. - if (TranslateExec(cf)) { - return 1; - } - } - - // main footer. - if (alloc_counts.positions) { - append( - " o.oPos = applyViewport(o.oPos);\n"); - } - append( - " return o;\n" - "};\n"); - - return 0; -} - -int D3D11ShaderTranslator::TranslatePixelShader( - PixelShaderResource* pixel_shader, - const xe_gpu_program_cntl_t& program_cntl, - const VertexShaderResource::AllocCounts& alloc_counts) { - SCOPE_profile_cpu_f("gpu"); - - // We need an input VS to make decisions here. - // TODO(benvanik): do we need to pair VS/PS up and store the combination? - // If the same PS is used with different VS that output different amounts - // (and less than the number of required registers), things may die. - - type_ = XE_GPU_SHADER_TYPE_PIXEL; - tex_fetch_index_ = 0; - dwords_ = pixel_shader->dwords(); - - // Add constants buffers. - // We could optimize this by only including used buffers, but the compiler - // seems to do a good job of doing this for us. - // It also does read detection, so c[512] can end up c[4] in the asm - - // instead of doing this optimization ourselves we could maybe just query - // this from the compiler. - append( - "cbuffer float_consts : register(b0) {\n" - " float4 c[512];\n" - "};\n"); - // TODO(benvanik): add bool/loop constants. - - AppendTextureHeader(pixel_shader->sampler_inputs()); - - // Add vertex shader output (pixel shader input). - append( - "struct VS_OUTPUT {\n"); - if (alloc_counts.positions) { - assert_true(alloc_counts.positions == 1); - append( - " float4 oPos : SV_POSITION;\n"); - } - if (alloc_counts.params) { - append( - " float4 o[%d] : XE_O;\n", - kMaxInterpolators); - } - append( - "};\n"); - - // Add pixel shader output. - append( - "struct PS_OUTPUT {\n"); - for (uint32_t n = 0; n < alloc_counts.params; n++) { - append( - " float4 oC%d : SV_TARGET%d;\n", n, n); - if (program_cntl.ps_export_depth) { - // Is this per render-target? - append( - " float oD%d : SV_DEPTH%d;\n", n, n); - } - } - append( - "};\n"); - - // Pixel shader main() header. - append( - "PS_OUTPUT main(VS_OUTPUT i) {\n" - " PS_OUTPUT o;\n"); - for (uint32_t n = 0; n < alloc_counts.params; n++) { - append( - " o.oC%d = float4(1.0, 0.0, 0.0, 1.0);\n", n); - } - - // Add temporary registers. - uint32_t temp_regs = program_cntl.vs_regs + program_cntl.ps_regs; - for (uint32_t n = 0; n <= std::max(15u, temp_regs); n++) { - append( - " float4 r%d = c[%d];\n", n, n + 256); - } - append(" float4 t;\n"); - append(" float s;\n"); // scalar result (used for RETAIN_PREV) - - // Bring registers local. - if (alloc_counts.params) { - for (uint32_t n = 0; n < kMaxInterpolators; n++) { - append( - " r%d = i.o[%d];\n", n, n); - } - } - - // Execute blocks. - const auto& execs = pixel_shader->execs(); - for (auto it = execs.begin(); it != execs.end(); ++it) { - const instr_cf_exec_t& cf = *it; - // TODO(benvanik): figure out how sequences/jmps/loops/etc work. - if (TranslateExec(cf)) { - return 1; - } - } - - // main footer. - append( - " return o;\n" - "}\n"); - - return 0; -} - -void D3D11ShaderTranslator::AppendTextureHeader( - const ShaderResource::SamplerInputs& sampler_inputs) { - bool fetch_setup[32] = { false }; - - // 1 texture per constant slot, 1 sampler per fetch. - for (uint32_t n = 0; n < sampler_inputs.count; n++) { - const auto& input = sampler_inputs.descs[n]; - const auto& fetch = input.tex_fetch; - - // Add texture, if needed. - if (!fetch_setup[fetch.const_idx]) { - fetch_setup[fetch.const_idx] = true; - const char* texture_type = NULL; - switch (fetch.dimension) { - case DIMENSION_1D: - texture_type = "Texture1D"; - break; - default: - case DIMENSION_2D: - texture_type = "Texture2D"; - break; - case DIMENSION_3D: - texture_type = "Texture3D"; - break; - case DIMENSION_CUBE: - texture_type = "TextureCube"; - break; - } - append("%s x_texture_%d;\n", texture_type, fetch.const_idx); - } - - // Add sampler. - append("SamplerState x_sampler_%d;\n", n); - } -} - -namespace { - -static const char chan_names[] = { - 'x', 'y', 'z', 'w', - // these only apply to FETCH dst's, and we shouldn't be using them: - '0', '1', '?', '_', -}; - -} // namespace - -void D3D11ShaderTranslator::AppendSrcReg(uint32_t num, uint32_t type, - uint32_t swiz, uint32_t negate, - uint32_t abs_constants) { - if (negate) { - append("-"); - } - if (type) { - // Register. - if (num & 0x80) { - append("abs("); - } - append("r%u", num & 0x7F); - if (num & 0x80) { - append(")"); - } - } else { - // Constant. - if (abs_constants) { - append("abs("); - } - append("c[%u]", type_ == XE_GPU_SHADER_TYPE_PIXEL ? num + 256 : num); - if (abs_constants) { - append(")"); - } - } - if (swiz) { - append("."); - for (int i = 0; i < 4; i++) { - append("%c", chan_names[(swiz + i) & 0x3]); - swiz >>= 2; - } - } -} - -void D3D11ShaderTranslator::AppendDestRegName(uint32_t num, uint32_t dst_exp) { - if (!dst_exp) { - // Register. - append("r%u", num); - } else { - // Export. - switch (type_) { - case XE_GPU_SHADER_TYPE_VERTEX: - switch (num) { - case 62: - append("o.oPos"); - break; - case 63: - append("o.oPointSize"); - break; - default: - // Varying. - append("o.o[%u]", num);; - break; - } - break; - case XE_GPU_SHADER_TYPE_PIXEL: - switch (num) { - case 0: - append("o.oC0"); - break; - default: - // TODO(benvanik): other render targets? - // TODO(benvanik): depth? - assert_always(); - break; - } - break; - } - } -} - -void D3D11ShaderTranslator::AppendDestReg(uint32_t num, uint32_t mask, - uint32_t dst_exp) { - if (mask != 0xF) { - // If masking, store to a temporary variable and clean it up later. - append("t"); - } else { - // Store directly to output. - AppendDestRegName(num, dst_exp); - } -} - -void D3D11ShaderTranslator::AppendDestRegPost(uint32_t num, uint32_t mask, - uint32_t dst_exp) { - if (mask != 0xF) { - // Masking. - append(" "); - AppendDestRegName(num, dst_exp); - append(" = float4("); - for (int i = 0; i < 4; i++) { - // TODO(benvanik): mask out values? mix in old value as temp? - // append("%c", (mask & 0x1) ? chan_names[i] : 'w'); - if (!(mask & 0x1)) { - AppendDestRegName(num, dst_exp); - } else { - append("t"); - } - append(".%c", chan_names[i]); - mask >>= 1; - if (i < 3) { - append(", "); - } - } - append(");\n"); - } -} - -void D3D11ShaderTranslator::PrintSrcReg(uint32_t num, uint32_t type, - uint32_t swiz, uint32_t negate, - uint32_t abs_constants) { - if (negate) { - append("-"); - } - if (type) { - if (num & 0x80) { - append("|"); - } - append("R%u", num & 0x7F); - if (num & 0x80) { - append("|"); - } - } else { - if (abs_constants) { - append("|"); - } - num += type_ == XE_GPU_SHADER_TYPE_PIXEL ? 256 : 0; - append("C%u", num); - if (abs_constants) { - append("|"); - } - } - if (swiz) { - append("."); - for (int i = 0; i < 4; i++) { - append("%c", chan_names[(swiz + i) & 0x3]); - swiz >>= 2; - } - } -} - -void D3D11ShaderTranslator::PrintDstReg(uint32_t num, uint32_t mask, - uint32_t dst_exp) { - append("%s%u", dst_exp ? "export" : "R", num); - if (mask != 0xf) { - append("."); - for (int i = 0; i < 4; i++) { - append("%c", (mask & 0x1) ? chan_names[i] : '_'); - mask >>= 1; - } - } -} - -void D3D11ShaderTranslator::PrintExportComment(uint32_t num) { - const char *name = NULL; - switch (type_) { - case XE_GPU_SHADER_TYPE_VERTEX: - switch (num) { - case 62: name = "gl_Position"; break; - case 63: name = "gl_PointSize"; break; - } - break; - case XE_GPU_SHADER_TYPE_PIXEL: - switch (num) { - case 0: name = "gl_FragColor"; break; - } - break; - } - /* if we had a symbol table here, we could look - * up the name of the varying.. - */ - if (name) { - append("\t; %s", name); - } -} - -int D3D11ShaderTranslator::TranslateALU_ADDv(const instr_alu_t& alu) { - AppendDestReg(alu.vector_dest, alu.vector_write_mask, alu.export_data); - append(" = "); - if (alu.vector_clamp) { - append("saturate("); - } - append("("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(" + "); - AppendSrcReg(alu.src2_reg, alu.src2_sel, alu.src2_swiz, alu.src2_reg_negate, alu.abs_constants); - append(")"); - if (alu.vector_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(alu.vector_dest, alu.vector_write_mask, alu.export_data); - return 0; -} - -int D3D11ShaderTranslator::TranslateALU_MULv(const instr_alu_t& alu) { - AppendDestReg(alu.vector_dest, alu.vector_write_mask, alu.export_data); - append(" = "); - if (alu.vector_clamp) { - append("saturate("); - } - append("("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(" * "); - AppendSrcReg(alu.src2_reg, alu.src2_sel, alu.src2_swiz, alu.src2_reg_negate, alu.abs_constants); - append(")"); - if (alu.vector_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(alu.vector_dest, alu.vector_write_mask, alu.export_data); - return 0; -} - -int D3D11ShaderTranslator::TranslateALU_MAXv(const instr_alu_t& alu) { - AppendDestReg(alu.vector_dest, alu.vector_write_mask, alu.export_data); - append(" = "); - if (alu.vector_clamp) { - append("saturate("); - } - if (alu.src1_reg == alu.src2_reg && - alu.src1_sel == alu.src2_sel && - alu.src1_swiz == alu.src2_swiz && - alu.src1_reg_negate == alu.src2_reg_negate) { - // This is a mov. - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - } else { - append("max("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(", "); - AppendSrcReg(alu.src2_reg, alu.src2_sel, alu.src2_swiz, alu.src2_reg_negate, alu.abs_constants); - append(")"); - } - if (alu.vector_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(alu.vector_dest, alu.vector_write_mask, alu.export_data); - return 0; -} - -int D3D11ShaderTranslator::TranslateALU_MINv(const instr_alu_t& alu) { - AppendDestReg(alu.vector_dest, alu.vector_write_mask, alu.export_data); - append(" = "); - if (alu.vector_clamp) { - append("saturate("); - } - append("min("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(", "); - AppendSrcReg(alu.src2_reg, alu.src2_sel, alu.src2_swiz, alu.src2_reg_negate, alu.abs_constants); - append(")"); - if (alu.vector_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(alu.vector_dest, alu.vector_write_mask, alu.export_data); - return 0; -} - -int D3D11ShaderTranslator::TranslateALU_SETXXv(const instr_alu_t& alu, const char* op) { - AppendDestReg(alu.vector_dest, alu.vector_write_mask, alu.export_data); - append(" = "); - if (alu.vector_clamp) { - append("saturate("); - } - append("float4(("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(").x %s (", op); - AppendSrcReg(alu.src2_reg, alu.src2_sel, alu.src2_swiz, alu.src2_reg_negate, alu.abs_constants); - append(").x ? 1.0 : 0.0, ("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(").y %s (", op); - AppendSrcReg(alu.src2_reg, alu.src2_sel, alu.src2_swiz, alu.src2_reg_negate, alu.abs_constants); - append(").y ? 1.0 : 0.0, ("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(").z %s (", op); - AppendSrcReg(alu.src2_reg, alu.src2_sel, alu.src2_swiz, alu.src2_reg_negate, alu.abs_constants); - append(").z ? 1.0 : 0.0, ("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(").w %s (", op); - AppendSrcReg(alu.src2_reg, alu.src2_sel, alu.src2_swiz, alu.src2_reg_negate, alu.abs_constants); - append(").w ? 1.0 : 0.0)"); - if (alu.vector_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(alu.vector_dest, alu.vector_write_mask, alu.export_data); - return 0; -} -int D3D11ShaderTranslator::TranslateALU_SETEv(const instr_alu_t& alu) { - return TranslateALU_SETXXv(alu, "=="); -} -int D3D11ShaderTranslator::TranslateALU_SETGTv(const instr_alu_t& alu) { - return TranslateALU_SETXXv(alu, ">"); -} -int D3D11ShaderTranslator::TranslateALU_SETGTEv(const instr_alu_t& alu) { - return TranslateALU_SETXXv(alu, ">="); -} -int D3D11ShaderTranslator::TranslateALU_SETNEv(const instr_alu_t& alu) { - return TranslateALU_SETXXv(alu, "!="); -} - -int D3D11ShaderTranslator::TranslateALU_FRACv(const instr_alu_t& alu) { - AppendDestReg(alu.vector_dest, alu.vector_write_mask, alu.export_data); - append(" = "); - if (alu.vector_clamp) { - append("saturate("); - } - append("frac("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(")"); - if (alu.vector_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(alu.vector_dest, alu.vector_write_mask, alu.export_data); - return 0; -} - -int D3D11ShaderTranslator::TranslateALU_TRUNCv(const instr_alu_t& alu) { - AppendDestReg(alu.vector_dest, alu.vector_write_mask, alu.export_data); - append(" = "); - if (alu.vector_clamp) { - append("saturate("); - } - append("trunc("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(")"); - if (alu.vector_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(alu.vector_dest, alu.vector_write_mask, alu.export_data); - return 0; -} - -int D3D11ShaderTranslator::TranslateALU_FLOORv(const instr_alu_t& alu) { - AppendDestReg(alu.vector_dest, alu.vector_write_mask, alu.export_data); - append(" = "); - if (alu.vector_clamp) { - append("saturate("); - } - append("floor("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(")"); - if (alu.vector_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(alu.vector_dest, alu.vector_write_mask, alu.export_data); - return 0; -} - -int D3D11ShaderTranslator::TranslateALU_MULADDv(const instr_alu_t& alu) { - AppendDestReg(alu.vector_dest, alu.vector_write_mask, alu.export_data); - append(" = "); - if (alu.vector_clamp) { - append("saturate("); - } - append("mad("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(", "); - AppendSrcReg(alu.src2_reg, alu.src2_sel, alu.src2_swiz, alu.src2_reg_negate, alu.abs_constants); - append(", "); - AppendSrcReg(alu.src3_reg, alu.src3_sel, alu.src3_swiz, alu.src3_reg_negate, alu.abs_constants); - append(")"); - if (alu.vector_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(alu.vector_dest, alu.vector_write_mask, alu.export_data); - return 0; -} - -int D3D11ShaderTranslator::TranslateALU_CNDXXv(const instr_alu_t& alu, const char* op) { - AppendDestReg(alu.vector_dest, alu.vector_write_mask, alu.export_data); - append(" = "); - if (alu.vector_clamp) { - append("saturate("); - } - // TODO(benvanik): check argument order - could be 3 as compare and 1 and 2 as values. - append("float4(("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(").x %s 0.0 ? (", op); - AppendSrcReg(alu.src2_reg, alu.src2_sel, alu.src2_swiz, alu.src2_reg_negate, alu.abs_constants); - append(").x : ("); - AppendSrcReg(alu.src3_reg, alu.src3_sel, alu.src3_swiz, alu.src3_reg_negate, alu.abs_constants); - append(").x, ("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(").y %s 0.0 ? (", op); - AppendSrcReg(alu.src2_reg, alu.src2_sel, alu.src2_swiz, alu.src2_reg_negate, alu.abs_constants); - append(").y : ("); - AppendSrcReg(alu.src3_reg, alu.src3_sel, alu.src3_swiz, alu.src3_reg_negate, alu.abs_constants); - append(").y, ("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(").z %s 0.0 ? (", op); - AppendSrcReg(alu.src2_reg, alu.src2_sel, alu.src2_swiz, alu.src2_reg_negate, alu.abs_constants); - append(").z : ("); - AppendSrcReg(alu.src3_reg, alu.src3_sel, alu.src3_swiz, alu.src3_reg_negate, alu.abs_constants); - append(").z, ("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(").w %s 0.0 ? (", op); - AppendSrcReg(alu.src2_reg, alu.src2_sel, alu.src2_swiz, alu.src2_reg_negate, alu.abs_constants); - append(").w : ("); - AppendSrcReg(alu.src3_reg, alu.src3_sel, alu.src3_swiz, alu.src3_reg_negate, alu.abs_constants); - append(").w)"); - if (alu.vector_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(alu.vector_dest, alu.vector_write_mask, alu.export_data); - return 0; -} -int D3D11ShaderTranslator::TranslateALU_CNDEv(const instr_alu_t& alu) { - return TranslateALU_CNDXXv(alu, "=="); -} -int D3D11ShaderTranslator::TranslateALU_CNDGTEv(const instr_alu_t& alu) { - return TranslateALU_CNDXXv(alu, ">="); -} -int D3D11ShaderTranslator::TranslateALU_CNDGTv(const instr_alu_t& alu) { - return TranslateALU_CNDXXv(alu, ">"); -} - -int D3D11ShaderTranslator::TranslateALU_DOT4v(const instr_alu_t& alu) { - AppendDestReg(alu.vector_dest, alu.vector_write_mask, alu.export_data); - append(" = "); - if (alu.vector_clamp) { - append("saturate("); - } - append("dot("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(", "); - AppendSrcReg(alu.src2_reg, alu.src2_sel, alu.src2_swiz, alu.src2_reg_negate, alu.abs_constants); - append(")"); - if (alu.vector_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(alu.vector_dest, alu.vector_write_mask, alu.export_data); - return 0; -} - -int D3D11ShaderTranslator::TranslateALU_DOT3v(const instr_alu_t& alu) { - AppendDestReg(alu.vector_dest, alu.vector_write_mask, alu.export_data); - append(" = "); - if (alu.vector_clamp) { - append("saturate("); - } - append("dot(float4("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(").xyz, float4("); - AppendSrcReg(alu.src2_reg, alu.src2_sel, alu.src2_swiz, alu.src2_reg_negate, alu.abs_constants); - append(").xyz)"); - if (alu.vector_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(alu.vector_dest, alu.vector_write_mask, alu.export_data); - return 0; -} - -int D3D11ShaderTranslator::TranslateALU_DOT2ADDv(const instr_alu_t& alu) { - AppendDestReg(alu.vector_dest, alu.vector_write_mask, alu.export_data); - append(" = "); - if (alu.vector_clamp) { - append("saturate("); - } - append("dot(float4("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(").xy, float4("); - AppendSrcReg(alu.src2_reg, alu.src2_sel, alu.src2_swiz, alu.src2_reg_negate, alu.abs_constants); - append(").xy) + "); - AppendSrcReg(alu.src3_reg, alu.src3_sel, alu.src3_swiz, alu.src3_reg_negate, alu.abs_constants); - append(".x"); - if (alu.vector_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(alu.vector_dest, alu.vector_write_mask, alu.export_data); - return 0; -} - -// CUBEv - -int D3D11ShaderTranslator::TranslateALU_MAX4v(const instr_alu_t& alu) { - AppendDestReg(alu.vector_dest, alu.vector_write_mask, alu.export_data); - append(" = "); - if (alu.vector_clamp) { - append("saturate("); - } - append("max("); - append("max("); - append("max("); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(".x, "); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(".y), "); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(".z), "); - AppendSrcReg(alu.src1_reg, alu.src1_sel, alu.src1_swiz, alu.src1_reg_negate, alu.abs_constants); - append(".w)"); - if (alu.vector_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(alu.vector_dest, alu.vector_write_mask, alu.export_data); - return 0; -} - -// ... - -int D3D11ShaderTranslator::TranslateALU_MAXs(const instr_alu_t& alu) { - AppendDestReg(get_alu_scalar_dest(alu), alu.scalar_write_mask, alu.export_data); - append(" = "); - if (alu.scalar_clamp) { - append("saturate("); - } - if ((alu.src3_swiz & 0x3) == (((alu.src3_swiz >> 2) + 1) & 0x3)) { - // This is a mov. - AppendSrcReg(alu.src3_reg, alu.src3_sel, alu.src3_swiz, alu.src3_reg_negate, alu.abs_constants); - } else { - append("max("); - AppendSrcReg(alu.src3_reg, alu.src3_sel, alu.src3_swiz, alu.src3_reg_negate, alu.abs_constants); - append(".x, "); - AppendSrcReg(alu.src3_reg, alu.src3_sel, alu.src3_swiz, alu.src3_reg_negate, alu.abs_constants); - append(".y).xxxx"); - } - if (alu.scalar_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(get_alu_scalar_dest(alu), alu.scalar_write_mask, alu.export_data); - return 0; -} - -int D3D11ShaderTranslator::TranslateALU_MINs(const instr_alu_t& alu) { - AppendDestReg(get_alu_scalar_dest(alu), alu.scalar_write_mask, alu.export_data); - append(" = "); - if (alu.scalar_clamp) { - append("saturate("); - } - append("min("); - AppendSrcReg(alu.src3_reg, alu.src3_sel, alu.src3_swiz, alu.src3_reg_negate, alu.abs_constants); - append(".x, "); - AppendSrcReg(alu.src3_reg, alu.src3_sel, alu.src3_swiz, alu.src3_reg_negate, alu.abs_constants); - append(".y).xxxx"); - if (alu.scalar_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(get_alu_scalar_dest(alu), alu.scalar_write_mask, alu.export_data); - return 0; -} - -int D3D11ShaderTranslator::TranslateALU_SETXXs(const instr_alu_t& alu, const char* op) { - AppendDestReg(get_alu_scalar_dest(alu), alu.scalar_write_mask, alu.export_data); - append(" = "); - if (alu.scalar_clamp) { - append("saturate("); - } - append("(("); - AppendSrcReg(alu.src3_reg, alu.src3_sel, alu.src3_swiz, alu.src3_reg_negate, alu.abs_constants); - append(".x %s 0.0) ? 1.0 : 0.0).xxxx", op); - if (alu.scalar_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(get_alu_scalar_dest(alu), alu.scalar_write_mask, alu.export_data); - return 0; -} -int D3D11ShaderTranslator::TranslateALU_SETEs(const instr_alu_t& alu) { - return TranslateALU_SETXXs(alu, "=="); -} -int D3D11ShaderTranslator::TranslateALU_SETGTs(const instr_alu_t& alu) { - return TranslateALU_SETXXs(alu, ">"); -} -int D3D11ShaderTranslator::TranslateALU_SETGTEs(const instr_alu_t& alu) { - return TranslateALU_SETXXs(alu, ">="); -} -int D3D11ShaderTranslator::TranslateALU_SETNEs(const instr_alu_t& alu) { - return TranslateALU_SETXXs(alu, "!="); -} - -int D3D11ShaderTranslator::TranslateALU_RECIP_IEEE(const instr_alu_t& alu) { - AppendDestReg(get_alu_scalar_dest(alu), alu.scalar_write_mask, alu.export_data); - append(" = "); - if (alu.scalar_clamp) { - append("saturate("); - } - append("(1.0 / "); - AppendSrcReg(alu.src3_reg, alu.src3_sel, alu.src3_swiz, alu.src3_reg_negate, alu.abs_constants); - append(")"); - if (alu.scalar_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(get_alu_scalar_dest(alu), alu.scalar_write_mask, alu.export_data); - return 0; -} - -int D3D11ShaderTranslator::TranslateALU_MUL_CONST_0(const instr_alu_t& alu) { - AppendDestReg(get_alu_scalar_dest(alu), alu.scalar_write_mask, alu.export_data); - append(" = "); - if (alu.scalar_clamp) { - append("saturate("); - } - uint32_t src3_swiz = alu.src3_swiz & ~0x3C; - uint32_t swiz_a = ((src3_swiz >> 6) - 1) & 0x3; - uint32_t swiz_b = (src3_swiz & 0x3); - uint32_t reg2 = (alu.scalar_opc & 1) | (alu.src3_swiz & 0x3C) | (alu.src3_sel << 1); - append("("); - AppendSrcReg(alu.src3_reg, 0, 0, alu.src3_reg_negate, alu.abs_constants); - append(".%c * ", chan_names[swiz_a]); - AppendSrcReg(reg2, 1, 0, alu.src3_reg_negate, alu.abs_constants); - append(".%c", chan_names[swiz_b]); - append(").xxxx"); - if (alu.scalar_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(get_alu_scalar_dest(alu), alu.scalar_write_mask, alu.export_data); - return 0; -} -int D3D11ShaderTranslator::TranslateALU_MUL_CONST_1(const instr_alu_t& alu) { - return TranslateALU_MUL_CONST_0(alu); -} - -int D3D11ShaderTranslator::TranslateALU_ADD_CONST_0(const instr_alu_t& alu) { - AppendDestReg(get_alu_scalar_dest(alu), alu.scalar_write_mask, alu.export_data); - append(" = "); - if (alu.scalar_clamp) { - append("saturate("); - } - uint32_t src3_swiz = alu.src3_swiz & ~0x3C; - uint32_t swiz_a = ((src3_swiz >> 6) - 1) & 0x3; - uint32_t swiz_b = (src3_swiz & 0x3); - uint32_t reg2 = (alu.scalar_opc & 1) | (alu.src3_swiz & 0x3C) | (alu.src3_sel << 1); - append("("); - AppendSrcReg(alu.src3_reg, 0, 0, alu.src3_reg_negate, alu.abs_constants); - append(".%c + ", chan_names[swiz_a]); - AppendSrcReg(reg2, 1, 0, alu.src3_reg_negate, alu.abs_constants); - append(".%c", chan_names[swiz_b]); - append(").xxxx"); - if (alu.scalar_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(get_alu_scalar_dest(alu), alu.scalar_write_mask, alu.export_data); - return 0; -} -int D3D11ShaderTranslator::TranslateALU_ADD_CONST_1(const instr_alu_t& alu) { - return TranslateALU_ADD_CONST_0(alu); -} - -int D3D11ShaderTranslator::TranslateALU_SUB_CONST_0(const instr_alu_t& alu) { - AppendDestReg(get_alu_scalar_dest(alu), alu.scalar_write_mask, alu.export_data); - append(" = "); - if (alu.scalar_clamp) { - append("saturate("); - } - uint32_t src3_swiz = alu.src3_swiz & ~0x3C; - uint32_t swiz_a = ((src3_swiz >> 6) - 1) & 0x3; - uint32_t swiz_b = (src3_swiz & 0x3); - uint32_t reg2 = (alu.scalar_opc & 1) | (alu.src3_swiz & 0x3C) | (alu.src3_sel << 1); - append("("); - AppendSrcReg(alu.src3_reg, 0, 0, alu.src3_reg_negate, alu.abs_constants); - append(".%c - ", chan_names[swiz_a]); - AppendSrcReg(reg2, 1, 0, alu.src3_reg_negate, alu.abs_constants); - append(".%c", chan_names[swiz_b]); - append(").xxxx"); - if (alu.scalar_clamp) { - append(")"); - } - append(";\n"); - AppendDestRegPost(get_alu_scalar_dest(alu), alu.scalar_write_mask, alu.export_data); - return 0; -} -int D3D11ShaderTranslator::TranslateALU_SUB_CONST_1(const instr_alu_t& alu) { - return TranslateALU_SUB_CONST_0(alu); -} - -int D3D11ShaderTranslator::TranslateALU_RETAIN_PREV(const instr_alu_t& alu) { - // TODO(benvanik): pull out prev value in s. - return 1; -} - -namespace { - -typedef int (D3D11ShaderTranslator::*TranslateFn)(const instr_alu_t& alu); -typedef struct { - uint32_t num_srcs; - const char* name; - TranslateFn fn; -} TranslateInfo; -#define ALU_INSTR(opc, num_srcs) \ - { num_srcs, #opc, nullptr } -#define ALU_INSTR_IMPL(opc, num_srcs) \ - { num_srcs, #opc, &D3D11ShaderTranslator::TranslateALU_##opc } - -} // namespace - -int D3D11ShaderTranslator::TranslateALU(const instr_alu_t* alu, int sync) { - static TranslateInfo vector_alu_instrs[0x20] = { - ALU_INSTR_IMPL(ADDv, 2), // 0 - ALU_INSTR_IMPL(MULv, 2), // 1 - ALU_INSTR_IMPL(MAXv, 2), // 2 - ALU_INSTR_IMPL(MINv, 2), // 3 - ALU_INSTR_IMPL(SETEv, 2), // 4 - ALU_INSTR_IMPL(SETGTv, 2), // 5 - ALU_INSTR_IMPL(SETGTEv, 2), // 6 - ALU_INSTR_IMPL(SETNEv, 2), // 7 - ALU_INSTR_IMPL(FRACv, 1), // 8 - ALU_INSTR_IMPL(TRUNCv, 1), // 9 - ALU_INSTR_IMPL(FLOORv, 1), // 10 - ALU_INSTR_IMPL(MULADDv, 3), // 11 - ALU_INSTR_IMPL(CNDEv, 3), // 12 - ALU_INSTR_IMPL(CNDGTEv, 3), // 13 - ALU_INSTR_IMPL(CNDGTv, 3), // 14 - ALU_INSTR_IMPL(DOT4v, 2), // 15 - ALU_INSTR_IMPL(DOT3v, 2), // 16 - ALU_INSTR_IMPL(DOT2ADDv, 3), // 17 -- ??? - ALU_INSTR(CUBEv, 2), // 18 - ALU_INSTR_IMPL(MAX4v, 1), // 19 - ALU_INSTR(PRED_SETE_PUSHv, 2), // 20 - ALU_INSTR(PRED_SETNE_PUSHv, 2), // 21 - ALU_INSTR(PRED_SETGT_PUSHv, 2), // 22 - ALU_INSTR(PRED_SETGTE_PUSHv, 2), // 23 - ALU_INSTR(KILLEv, 2), // 24 - ALU_INSTR(KILLGTv, 2), // 25 - ALU_INSTR(KILLGTEv, 2), // 26 - ALU_INSTR(KILLNEv, 2), // 27 - ALU_INSTR(DSTv, 2), // 28 - ALU_INSTR(MOVAv, 1), // 29 - }; - static TranslateInfo scalar_alu_instrs[0x40] = { - ALU_INSTR(ADDs, 1), // 0 - ALU_INSTR(ADD_PREVs, 1), // 1 - ALU_INSTR(MULs, 1), // 2 - ALU_INSTR(MUL_PREVs, 1), // 3 - ALU_INSTR(MUL_PREV2s, 1), // 4 - ALU_INSTR_IMPL(MAXs, 1), // 5 - ALU_INSTR_IMPL(MINs, 1), // 6 - ALU_INSTR_IMPL(SETEs, 1), // 7 - ALU_INSTR_IMPL(SETGTs, 1), // 8 - ALU_INSTR_IMPL(SETGTEs, 1), // 9 - ALU_INSTR_IMPL(SETNEs, 1), // 10 - ALU_INSTR(FRACs, 1), // 11 - ALU_INSTR(TRUNCs, 1), // 12 - ALU_INSTR(FLOORs, 1), // 13 - ALU_INSTR(EXP_IEEE, 1), // 14 - ALU_INSTR(LOG_CLAMP, 1), // 15 - ALU_INSTR(LOG_IEEE, 1), // 16 - ALU_INSTR(RECIP_CLAMP, 1), // 17 - ALU_INSTR(RECIP_FF, 1), // 18 - ALU_INSTR_IMPL(RECIP_IEEE, 1), // 19 - ALU_INSTR(RECIPSQ_CLAMP, 1), // 20 - ALU_INSTR(RECIPSQ_FF, 1), // 21 - ALU_INSTR(RECIPSQ_IEEE, 1), // 22 - ALU_INSTR(MOVAs, 1), // 23 - ALU_INSTR(MOVA_FLOORs, 1), // 24 - ALU_INSTR(SUBs, 1), // 25 - ALU_INSTR(SUB_PREVs, 1), // 26 - ALU_INSTR(PRED_SETEs, 1), // 27 - ALU_INSTR(PRED_SETNEs, 1), // 28 - ALU_INSTR(PRED_SETGTs, 1), // 29 - ALU_INSTR(PRED_SETGTEs, 1), // 30 - ALU_INSTR(PRED_SET_INVs, 1), // 31 - ALU_INSTR(PRED_SET_POPs, 1), // 32 - ALU_INSTR(PRED_SET_CLRs, 1), // 33 - ALU_INSTR(PRED_SET_RESTOREs, 1), // 34 - ALU_INSTR(KILLEs, 1), // 35 - ALU_INSTR(KILLGTs, 1), // 36 - ALU_INSTR(KILLGTEs, 1), // 37 - ALU_INSTR(KILLNEs, 1), // 38 - ALU_INSTR(KILLONEs, 1), // 39 - ALU_INSTR(SQRT_IEEE, 1), // 40 - { 0, 0, false }, - ALU_INSTR_IMPL(MUL_CONST_0, 2), // 42 - ALU_INSTR_IMPL(MUL_CONST_1, 2), // 43 - ALU_INSTR_IMPL(ADD_CONST_0, 2), // 44 - ALU_INSTR_IMPL(ADD_CONST_1, 2), // 45 - ALU_INSTR_IMPL(SUB_CONST_0, 2), // 46 - ALU_INSTR_IMPL(SUB_CONST_1, 2), // 47 - ALU_INSTR(SIN, 1), // 48 - ALU_INSTR(COS, 1), // 49 - ALU_INSTR(RETAIN_PREV, 1), // 50 - }; -#undef ALU_INSTR -#undef ALU_INSTR_IMPL - - if (!alu->scalar_write_mask && !alu->vector_write_mask) { - append(" // \n"); - return 0; - } - - if (alu->vector_write_mask) { - // Disassemble vector op. - const auto& iv = vector_alu_instrs[alu->vector_opc]; - append(" // %sALU:\t", sync ? "(S)" : " "); - append("%s", iv.name); - if (alu->pred_select & 0x2) { - // seems to work similar to conditional execution in ARM instruction - // set, so let's use a similar syntax for now: - append((alu->pred_select & 0x1) ? "EQ" : "NE"); - } - append("\t"); - PrintDstReg(alu->vector_dest, alu->vector_write_mask, alu->export_data); - append(" = "); - if (iv.num_srcs == 3) { - PrintSrcReg(alu->src3_reg, alu->src3_sel, alu->src3_swiz, - alu->src3_reg_negate, alu->abs_constants); - append(", "); - } - PrintSrcReg(alu->src1_reg, alu->src1_sel, alu->src1_swiz, - alu->src1_reg_negate, alu->abs_constants); - if (iv.num_srcs > 1) { - append(", "); - PrintSrcReg(alu->src2_reg, alu->src2_sel, alu->src2_swiz, - alu->src2_reg_negate, alu->abs_constants); - } - if (alu->vector_clamp) { - append(" CLAMP"); - } - if (alu->export_data) { - PrintExportComment(alu->vector_dest); - } - append("\n"); - - // Translate vector op. - if (iv.fn) { - append(" "); - if ((this->*iv.fn)(*alu)) { - return 1; - } - } else { - append(" // \n"); - } - } - - if (alu->scalar_write_mask || !alu->vector_write_mask) { - // 2nd optional scalar op: - - // Disassemble scalar op. - const auto& is = scalar_alu_instrs[alu->scalar_opc]; - append(" // "); - append("\t"); - if (is.name) { - append("\t \t%s\t", is.name); - } else { - append("\t \tOP(%u)\t", alu->scalar_opc); - } - PrintDstReg(get_alu_scalar_dest(*alu), alu->scalar_write_mask, alu->export_data); - append(" = "); - if (is.num_srcs == 2) { - // ADD_CONST_0 dest, [const], [reg] - uint32_t src3_swiz = alu->src3_swiz & ~0x3C; - uint32_t swiz_a = ((src3_swiz >> 6) - 1) & 0x3; - uint32_t swiz_b = (src3_swiz & 0x3); - PrintSrcReg(alu->src3_reg, 0, 0, - alu->src3_reg_negate, alu->abs_constants); - append(".%c", chan_names[swiz_a]); - append(", "); - uint32_t reg2 = (alu->scalar_opc & 1) | (alu->src3_swiz & 0x3C) | (alu->src3_sel << 1); - PrintSrcReg(reg2, 1, 0, - alu->src3_reg_negate, alu->abs_constants); - append(".%c", chan_names[swiz_b]); - } else { - PrintSrcReg(alu->src3_reg, alu->src3_sel, alu->src3_swiz, - alu->src3_reg_negate, alu->abs_constants); - } - if (alu->scalar_clamp) { - append(" CLAMP"); - } - if (alu->export_data) { - PrintExportComment(get_alu_scalar_dest(*alu)); - } - append("\n"); - - // Translate scalar op. - if (is.fn) { - append(" "); - if ((this->*is.fn)(*alu)) { - return 1; - } - } else { - append(" // \n"); - } - } - - return 0; -} - -void D3D11ShaderTranslator::PrintDestFecth(uint32_t dst_reg, - uint32_t dst_swiz) { - append("\tR%u.", dst_reg); - for (int i = 0; i < 4; i++) { - append("%c", chan_names[dst_swiz & 0x7]); - dst_swiz >>= 3; - } -} - -void D3D11ShaderTranslator::AppendFetchDest(uint32_t dst_reg, - uint32_t dst_swiz) { - append("r%u.", dst_reg); - for (int i = 0; i < 4; i++) { - append("%c", chan_names[dst_swiz & 0x7]); - dst_swiz >>= 3; - } -} - -int D3D11ShaderTranslator::GetFormatComponentCount(uint32_t format) { - switch (format) { - case FMT_32: - case FMT_32_FLOAT: - return 1; - case FMT_16_16: - case FMT_16_16_FLOAT: - case FMT_32_32: - case FMT_32_32_FLOAT: - return 2; - case FMT_10_11_11: - case FMT_11_11_10: - case FMT_32_32_32_FLOAT: - return 3; - case FMT_8_8_8_8: - case FMT_2_10_10_10: - case FMT_16_16_16_16: - case FMT_16_16_16_16_FLOAT: - case FMT_32_32_32_32: - case FMT_32_32_32_32_FLOAT: - return 4; - default: - XELOGE("Unknown vertex format: %d", format); - assert_always(); - return 4; - } -} - -int D3D11ShaderTranslator::TranslateExec(const instr_cf_exec_t& cf) { - static const struct { - const char *name; - } cf_instructions[] = { - #define INSTR(opc, fxn) { #opc } - INSTR(NOP, print_cf_nop), - INSTR(EXEC, print_cf_exec), - INSTR(EXEC_END, print_cf_exec), - INSTR(COND_EXEC, print_cf_exec), - INSTR(COND_EXEC_END, print_cf_exec), - INSTR(COND_PRED_EXEC, print_cf_exec), - INSTR(COND_PRED_EXEC_END, print_cf_exec), - INSTR(LOOP_START, print_cf_loop), - INSTR(LOOP_END, print_cf_loop), - INSTR(COND_CALL, print_cf_jmp_call), - INSTR(RETURN, print_cf_jmp_call), - INSTR(COND_JMP, print_cf_jmp_call), - INSTR(ALLOC, print_cf_alloc), - INSTR(COND_EXEC_PRED_CLEAN, print_cf_exec), - INSTR(COND_EXEC_PRED_CLEAN_END, print_cf_exec), - INSTR(MARK_VS_FETCH_DONE, print_cf_nop), // ?? - #undef INSTR - }; - - append( - " // %s ADDR(0x%x) CNT(0x%x)", - cf_instructions[cf.opc].name, cf.address, cf.count); - if (cf.yeild) { - append(" YIELD"); - } - uint8_t vc = cf.vc_hi | (cf.vc_lo << 2); - if (vc) { - append(" VC(0x%x)", vc); - } - if (cf.bool_addr) { - append(" BOOL_ADDR(0x%x)", cf.bool_addr); - } - if (cf.address_mode == ABSOLUTE_ADDR) { - append(" ABSOLUTE_ADDR"); - } - if (cf.is_cond_exec()) { - append(" COND(%d)", cf.condition); - } - append("\n"); - - uint32_t sequence = cf.serialize; - for (uint32_t i = 0; i < cf.count; i++) { - uint32_t alu_off = (cf.address + i); - int sync = sequence & 0x2; - if (sequence & 0x1) { - const instr_fetch_t* fetch = - (const instr_fetch_t*)(dwords_ + alu_off * 3); - switch (fetch->opc) { - case VTX_FETCH: - if (TranslateVertexFetch(&fetch->vtx, sync)) { - return 1; - } - break; - case TEX_FETCH: - if (TranslateTextureFetch(&fetch->tex, sync)) { - return 1; - } - break; - case TEX_GET_BORDER_COLOR_FRAC: - case TEX_GET_COMP_TEX_LOD: - case TEX_GET_GRADIENTS: - case TEX_GET_WEIGHTS: - case TEX_SET_TEX_LOD: - case TEX_SET_GRADIENTS_H: - case TEX_SET_GRADIENTS_V: - default: - assert_always(); - break; - } - } else { - const instr_alu_t* alu = - (const instr_alu_t*)(dwords_ + alu_off * 3); - if (TranslateALU(alu, sync)) { - return 1; - } - } - sequence >>= 2; - } - - return 0; -} - -int D3D11ShaderTranslator::TranslateVertexFetch(const instr_fetch_vtx_t* vtx, - int sync) { - static const struct { - const char *name; - } fetch_types[0xff] = { - #define TYPE(id) { #id } - TYPE(FMT_1_REVERSE), // 0 - {0}, - TYPE(FMT_8), // 2 - {0}, - {0}, - {0}, - TYPE(FMT_8_8_8_8), // 6 - TYPE(FMT_2_10_10_10), // 7 - {0}, - {0}, - TYPE(FMT_8_8), // 10 - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - TYPE(FMT_16), // 24 - TYPE(FMT_16_16), // 25 - TYPE(FMT_16_16_16_16), // 26 - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - TYPE(FMT_32), // 33 - TYPE(FMT_32_32), // 34 - TYPE(FMT_32_32_32_32), // 35 - TYPE(FMT_32_FLOAT), // 36 - TYPE(FMT_32_32_FLOAT), // 37 - TYPE(FMT_32_32_32_32_FLOAT), // 38 - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - {0}, - TYPE(FMT_32_32_32_FLOAT), // 57 - #undef TYPE - }; - - // Disassemble. - append(" // %sFETCH:\t", sync ? "(S)" : " "); - if (vtx->pred_select) { - append(vtx->pred_condition ? "EQ" : "NE"); - } - PrintDestFecth(vtx->dst_reg, vtx->dst_swiz); - append(" = R%u.", vtx->src_reg); - append("%c", chan_names[vtx->src_swiz & 0x3]); - if (fetch_types[vtx->format].name) { - append(" %s", fetch_types[vtx->format].name); - } else { - append(" TYPE(0x%x)", vtx->format); - } - append(" %s", vtx->format_comp_all ? "SIGNED" : "UNSIGNED"); - if (!vtx->num_format_all) { - append(" NORMALIZED"); - } - append(" STRIDE(%u)", vtx->stride); - if (vtx->offset) { - append(" OFFSET(%u)", vtx->offset); - } - append(" CONST(%u, %u)", vtx->const_index, vtx->const_index_sel); - if (1) { - // XXX - append(" src_reg_am=%u", vtx->src_reg_am); - append(" dst_reg_am=%u", vtx->dst_reg_am); - append(" num_format_all=%u", vtx->num_format_all); - append(" signed_rf_mode_all=%u", vtx->signed_rf_mode_all); - append(" exp_adjust_all=%u", vtx->exp_adjust_all); - } - append("\n"); - - // Translate. - append(" "); - append("r%u.xyzw", vtx->dst_reg); - append(" = float4("); - uint32_t fetch_slot = vtx->const_index * 3 + vtx->const_index_sel; - // TODO(benvanik): detect xyzw = xyzw, etc. - // TODO(benvanik): detect and set as rN = float4(samp.xyz, 1.0); / etc - uint32_t component_count = GetFormatComponentCount(vtx->format); - uint32_t dst_swiz = vtx->dst_swiz; - for (int i = 0; i < 4; i++) { - if ((dst_swiz & 0x7) == 4) { - append("0.0"); - } else if ((dst_swiz & 0x7) == 5) { - append("1.0"); - } else if ((dst_swiz & 0x7) == 6) { - // ? - append("?"); - } else if ((dst_swiz & 0x7) == 7) { - append("r%u.%c", vtx->dst_reg, chan_names[i]); - } else { - append("i.vf%u_%d.%c", - fetch_slot, vtx->offset, - chan_names[dst_swiz & 0x3]); - } - if (i < 3) { - append(", "); - } - dst_swiz >>= 3; - } - append(");\n"); - return 0; -} - -int D3D11ShaderTranslator::TranslateTextureFetch(const instr_fetch_tex_t* tex, - int sync) { - int src_component_count = 0; - switch (tex->dimension) { - case DIMENSION_1D: - src_component_count = 1; - break; - default: - case DIMENSION_2D: - src_component_count = 2; - break; - case DIMENSION_3D: - src_component_count = 3; - break; - case DIMENSION_CUBE: - src_component_count = 3; - break; - } - - // Disassemble. - static const char *filter[] = { - "POINT", // TEX_FILTER_POINT - "LINEAR", // TEX_FILTER_LINEAR - "BASEMAP", // TEX_FILTER_BASEMAP - }; - static const char *aniso_filter[] = { - "DISABLED", // ANISO_FILTER_DISABLED - "MAX_1_1", // ANISO_FILTER_MAX_1_1 - "MAX_2_1", // ANISO_FILTER_MAX_2_1 - "MAX_4_1", // ANISO_FILTER_MAX_4_1 - "MAX_8_1", // ANISO_FILTER_MAX_8_1 - "MAX_16_1", // ANISO_FILTER_MAX_16_1 - }; - static const char *arbitrary_filter[] = { - "2x4_SYM", // ARBITRARY_FILTER_2X4_SYM - "2x4_ASYM", // ARBITRARY_FILTER_2X4_ASYM - "4x2_SYM", // ARBITRARY_FILTER_4X2_SYM - "4x2_ASYM", // ARBITRARY_FILTER_4X2_ASYM - "4x4_SYM", // ARBITRARY_FILTER_4X4_SYM - "4x4_ASYM", // ARBITRARY_FILTER_4X4_ASYM - }; - static const char *sample_loc[] = { - "CENTROID", // SAMPLE_CENTROID - "CENTER", // SAMPLE_CENTER - }; - uint32_t src_swiz = tex->src_swiz; - append(" // %sFETCH:\t", sync ? "(S)" : " "); - if (tex->pred_select) { - append(tex->pred_condition ? "EQ" : "NE"); - } - PrintDestFecth(tex->dst_reg, tex->dst_swiz); - append(" = R%u.", tex->src_reg); - for (int i = 0; i < src_component_count; i++) { - append("%c", chan_names[src_swiz & 0x3]); - src_swiz >>= 2; - } - append(" CONST(%u)", tex->const_idx); - if (tex->fetch_valid_only) { - append(" VALID_ONLY"); - } - if (tex->tx_coord_denorm) { - append(" DENORM"); - } - if (tex->mag_filter != TEX_FILTER_USE_FETCH_CONST) { - append(" MAG(%s)", filter[tex->mag_filter]); - } - if (tex->min_filter != TEX_FILTER_USE_FETCH_CONST) { - append(" MIN(%s)", filter[tex->min_filter]); - } - if (tex->mip_filter != TEX_FILTER_USE_FETCH_CONST) { - append(" MIP(%s)", filter[tex->mip_filter]); - } - if (tex->aniso_filter != ANISO_FILTER_USE_FETCH_CONST) { - append(" ANISO(%s)", aniso_filter[tex->aniso_filter]); - } - if (tex->arbitrary_filter != ARBITRARY_FILTER_USE_FETCH_CONST) { - append(" ARBITRARY(%s)", arbitrary_filter[tex->arbitrary_filter]); - } - if (tex->vol_mag_filter != TEX_FILTER_USE_FETCH_CONST) { - append(" VOL_MAG(%s)", filter[tex->vol_mag_filter]); - } - if (tex->vol_min_filter != TEX_FILTER_USE_FETCH_CONST) { - append(" VOL_MIN(%s)", filter[tex->vol_min_filter]); - } - if (!tex->use_comp_lod) { - append(" LOD(%u)", tex->use_comp_lod); - append(" LOD_BIAS(%u)", tex->lod_bias); - } - if (tex->use_reg_lod) { - append(" REG_LOD(%u)", tex->use_reg_lod); - } - if (tex->use_reg_gradients) { - append(" USE_REG_GRADIENTS"); - } - append(" LOCATION(%s)", sample_loc[tex->sample_location]); - if (tex->offset_x || tex->offset_y || tex->offset_z) { - append(" OFFSET(%u,%u,%u)", tex->offset_x, tex->offset_y, tex->offset_z); - } - append("\n"); - - // Translate. - append(" t = "); - append( - "x_texture_%d.Sample(x_sampler_%d, r%u.", - tex->const_idx, - tex_fetch_index_++, // hacky way to line up to tex buffers - tex->src_reg); - src_swiz = tex->src_swiz; - for (int i = 0; i < src_component_count; i++) { - append("%c", chan_names[src_swiz & 0x3]); - src_swiz >>= 2; - } - append(");\n"); - - append(" r%u.xyzw = float4(", tex->dst_reg); - uint32_t dst_swiz = tex->dst_swiz; - for (int i = 0; i < 4; i++) { - if (i) { - append(", "); - } - if ((dst_swiz & 0x7) == 4) { - append("0.0"); - } else if ((dst_swiz & 0x7) == 5) { - append("1.0"); - } else if ((dst_swiz & 0x7) == 6) { - // ? - append("?"); - } else if ((dst_swiz & 0x7) == 7) { - append("r%u.%c", tex->dst_reg, chan_names[i]); - } else { - append("t.%c", chan_names[dst_swiz & 0x3]); - } - dst_swiz >>= 3; - } - append(");\n"); - return 0; -} diff --git a/src/xenia/gpu/d3d11/d3d11_shader_translator.h b/src/xenia/gpu/d3d11/d3d11_shader_translator.h deleted file mode 100644 index 72be1aee8..000000000 --- a/src/xenia/gpu/d3d11/d3d11_shader_translator.h +++ /dev/null @@ -1,125 +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_SHADER_TRANSLATOR_H_ -#define XENIA_GPU_D3D11_D3D11_SHADER_TRANSLATOR_H_ - -#include -#include - -#include - - -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 = vsnprintf(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); - int TranslateALU_RETAIN_PREV(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_ diff --git a/src/xenia/gpu/d3d11/d3d11_texture_resource.cc b/src/xenia/gpu/d3d11/d3d11_texture_resource.cc deleted file mode 100644 index ebe57fdb1..000000000 --- a/src/xenia/gpu/d3d11/d3d11_texture_resource.cc +++ /dev/null @@ -1,216 +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 - -#include -#include - - -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() { - SafeRelease(texture_); - SafeRelease(handle_); -} - -int D3D11TextureResource::CreateHandle() { - SCOPE_profile_cpu_f("gpu"); - - D3D11_SHADER_RESOURCE_VIEW_DESC 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 = {}; - 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 = {}; - 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"); - assert_always(); - return 1; -} - -int D3D11TextureResource::CreateHandleCube() { - XELOGE("D3D11: CreateTextureCube not yet implemented"); - assert_always(); - 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; -} diff --git a/src/xenia/gpu/d3d11/d3d11_texture_resource.h b/src/xenia/gpu/d3d11/d3d11_texture_resource.h deleted file mode 100644 index 9ca3bd0e5..000000000 --- a/src/xenia/gpu/d3d11/d3d11_texture_resource.h +++ /dev/null @@ -1,59 +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_RESOURCE_H_ -#define XENIA_GPU_D3D11_D3D11_TEXTURE_RESOURCE_H_ - -#include -#include -#include - - -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_ diff --git a/src/xenia/gpu/d3d11/d3d11_window.cc b/src/xenia/gpu/d3d11/d3d11_window.cc deleted file mode 100644 index c99cdc421..000000000 --- a/src/xenia/gpu/d3d11/d3d11_window.cc +++ /dev/null @@ -1,140 +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 - -#include - - -using namespace xe; -using namespace xe::gpu; -using namespace xe::gpu::d3d11; -using namespace xe::ui; -using namespace xe::ui::win32; - - -D3D11Window::D3D11Window( - xe_run_loop_ref run_loop, - IDXGIFactory1* dxgi_factory, ID3D11Device* device) : - Win32Window(run_loop) { - dxgi_factory_ = dxgi_factory; - dxgi_factory_->AddRef(); - device_ = device; - device_->AddRef(); - device_->GetImmediateContext(&context_); - - swap_chain_ = 0; - render_target_view_ = 0; - - closing.AddListener([](UIEvent& e) { - xe_run_loop_quit(e.window()->run_loop()); - }); -} - -D3D11Window::~D3D11Window() { - Profiler::set_display(nullptr); - if (context_) { - context_->ClearState(); - } - SafeRelease(render_target_view_); - SafeRelease(context_); - SafeRelease(swap_chain_); - SafeRelease(device_); - SafeRelease(dxgi_factory_); -} - -int D3D11Window::Initialize(const std::wstring& title, uint32_t width, - uint32_t height) { - int result = Win32Window::Initialize(title, width, height); - if (result) { - return result; - } - - // Setup swap chain. - DXGI_SWAP_CHAIN_DESC desc = {}; - desc.OutputWindow = handle(); - desc.Windowed = TRUE; - desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; - desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; - - // Setup buffers. - desc.BufferCount = 2; - desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - desc.BufferDesc.Width = width; - desc.BufferDesc.Height = height; - desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.BufferDesc.RefreshRate.Numerator = 60; - desc.BufferDesc.RefreshRate.Denominator = 1; - - // Disable multisampling. - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - - // Create! - HRESULT hr = dxgi_factory_->CreateSwapChain( - device_, - &desc, - &swap_chain_); - if (FAILED(hr)) { - XELOGE("CreateSwapChain failed with %.8X", hr); - return 1; - } - - // Create a render target view to draw into. - ID3D11Texture2D* back_buffer = 0; - hr = swap_chain_->GetBuffer( - 0, __uuidof(ID3D11Texture2D), (void**)&back_buffer); - if (FAILED(hr)) { - XELOGE("GetBuffer (back_buffer) failed with %.8X", hr); - return 1; - } - hr = device_->CreateRenderTargetView( - back_buffer, NULL, &render_target_view_); - back_buffer->Release(); - if (FAILED(hr)) { - XELOGE("CreateRenderTargetView (back_buffer) failed with %.8X", hr); - return 1; - } - context_->OMSetRenderTargets(1, &render_target_view_, NULL); - - // Setup profiler display. - if (Profiler::is_enabled()) { - std::unique_ptr profiler_display( - new D3D11ProfilerDisplay(this)); - Profiler::set_display(std::move(profiler_display)); - } - - return 0; -} - -void D3D11Window::Swap() { - SCOPE_profile_cpu_f("gpu"); - - // Present profiler. - context_->OMSetRenderTargets(1, &render_target_view_, NULL); - Profiler::Present(); - - // Swap buffers. - // TODO(benvanik): control vsync with flag. - bool vsync = true; - HRESULT hr = swap_chain_->Present(vsync ? 1 : 0, 0); - if (FAILED(hr)) { - XELOGE("Present failed with %.8X", hr); - } -} - -bool D3D11Window::OnResize(uint32_t width, uint32_t height) { - if (!Win32Window::OnResize(width, height)) { - return false; - } - - // TODO(benvanik): resize swap buffers? - - return true; -} diff --git a/src/xenia/gpu/d3d11/d3d11_window.h b/src/xenia/gpu/d3d11/d3d11_window.h deleted file mode 100644 index afc6cd51b..000000000 --- a/src/xenia/gpu/d3d11/d3d11_window.h +++ /dev/null @@ -1,52 +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_WINDOW_H_ -#define XENIA_GPU_D3D11_D3D11_WINDOW_H_ - -#include -#include -#include - -namespace xe { -namespace gpu { -namespace d3d11 { - -class D3D11Window : public xe::ui::win32::Win32Window { -public: - D3D11Window( - xe_run_loop_ref run_loop, - IDXGIFactory1* dxgi_factory, ID3D11Device* device); - ~D3D11Window() override; - - ID3D11Device* device() const { return device_; } - IDXGISwapChain* swap_chain() const { return swap_chain_; } - ID3D11DeviceContext* context() const { return context_; } - - int Initialize(const std::wstring& title, uint32_t width, - uint32_t height) override; - - void Swap(); - -protected: - bool OnResize(uint32_t width, uint32_t height) override; - -private: - IDXGIFactory1* dxgi_factory_; - ID3D11Device* device_; - IDXGISwapChain* swap_chain_; - ID3D11DeviceContext* context_; - ID3D11RenderTargetView* render_target_view_; -}; - -} // namespace d3d11 -} // namespace gpu -} // namespace xe - -#endif // XENIA_GPU_D3D11_D3D11_WINDOW_H_ diff --git a/src/xenia/gpu/d3d11/sources.gypi b/src/xenia/gpu/d3d11/sources.gypi deleted file mode 100644 index b6b6d76c1..000000000 --- a/src/xenia/gpu/d3d11/sources.gypi +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2013 Ben Vanik. All Rights Reserved. -{ - 'sources': [ - 'd3d11_buffer_resource.cc', - 'd3d11_buffer_resource.h', - 'd3d11_geometry_shader.cc', - 'd3d11_geometry_shader.h', - 'd3d11_gpu-private.h', - 'd3d11_gpu.cc', - 'd3d11_gpu.h', - 'd3d11_graphics_driver.cc', - 'd3d11_graphics_driver.h', - 'd3d11_graphics_system.cc', - 'd3d11_graphics_system.h', - 'd3d11_profiler_display.cc', - 'd3d11_profiler_display.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', - ], -}