[Vulkan] Remove old Vulkan code, change shaders directory, create empty Vulkan backend

This commit is contained in:
Triang3l
2020-08-31 21:44:29 +03:00
parent 1e9ee8f43b
commit 7b93670dbd
461 changed files with 161 additions and 22194 deletions

View File

@@ -1,809 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/gpu/vulkan/buffer_cache.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/memory.h"
#include "xenia/base/profiling.h"
#include "xenia/gpu/gpu_flags.h"
#include "xenia/gpu/vulkan/vulkan_gpu_flags.h"
#include "xenia/ui/vulkan/vulkan_mem_alloc.h"
using namespace xe::gpu::xenos;
namespace xe {
namespace gpu {
namespace vulkan {
#if XE_ARCH_AMD64
void copy_cmp_swap_16_unaligned(void* dest_ptr, const void* src_ptr,
uint16_t cmp_value, size_t count) {
auto dest = reinterpret_cast<uint16_t*>(dest_ptr);
auto src = reinterpret_cast<const uint16_t*>(src_ptr);
__m128i shufmask =
_mm_set_epi8(0x0E, 0x0F, 0x0C, 0x0D, 0x0A, 0x0B, 0x08, 0x09, 0x06, 0x07,
0x04, 0x05, 0x02, 0x03, 0x00, 0x01);
__m128i cmpval = _mm_set1_epi16(cmp_value);
size_t i;
for (i = 0; i + 8 <= count; i += 8) {
__m128i input = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&src[i]));
__m128i output = _mm_shuffle_epi8(input, shufmask);
__m128i mask = _mm_cmpeq_epi16(output, cmpval);
output = _mm_or_si128(output, mask);
_mm_storeu_si128(reinterpret_cast<__m128i*>(&dest[i]), output);
}
for (; i < count; ++i) { // handle residual elements
dest[i] = byte_swap(src[i]);
}
}
void copy_cmp_swap_32_unaligned(void* dest_ptr, const void* src_ptr,
uint32_t cmp_value, size_t count) {
auto dest = reinterpret_cast<uint32_t*>(dest_ptr);
auto src = reinterpret_cast<const uint32_t*>(src_ptr);
__m128i shufmask =
_mm_set_epi8(0x0C, 0x0D, 0x0E, 0x0F, 0x08, 0x09, 0x0A, 0x0B, 0x04, 0x05,
0x06, 0x07, 0x00, 0x01, 0x02, 0x03);
__m128i cmpval = _mm_set1_epi32(cmp_value);
size_t i;
for (i = 0; i + 4 <= count; i += 4) {
__m128i input = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&src[i]));
__m128i output = _mm_shuffle_epi8(input, shufmask);
__m128i mask = _mm_cmpeq_epi32(output, cmpval);
output = _mm_or_si128(output, mask);
_mm_storeu_si128(reinterpret_cast<__m128i*>(&dest[i]), output);
}
for (; i < count; ++i) { // handle residual elements
dest[i] = byte_swap(src[i]);
}
}
#else
void copy_and_swap_16_unaligned(void* dest_ptr, const void* src_ptr,
uint16_t cmp_value, size_t count) {
auto dest = reinterpret_cast<uint16_t*>(dest_ptr);
auto src = reinterpret_cast<const uint16_t*>(src_ptr);
for (size_t i = 0; i < count; ++i) {
uint16_t value = byte_swap(src[i]);
dest[i] = value == cmp_value ? 0xFFFF : value;
}
}
void copy_and_swap_32_unaligned(void* dest_ptr, const void* src_ptr,
uint32_t cmp_value, size_t count) {
auto dest = reinterpret_cast<uint32_t*>(dest_ptr);
auto src = reinterpret_cast<const uint32_t*>(src_ptr);
for (size_t i = 0; i < count; ++i) {
uint32_t value = byte_swap(src[i]);
dest[i] = value == cmp_value ? 0xFFFFFFFF : value;
}
}
#endif
using xe::ui::vulkan::CheckResult;
constexpr VkDeviceSize kConstantRegisterUniformRange =
512 * 4 * 4 + 8 * 4 + 32 * 4;
BufferCache::BufferCache(RegisterFile* register_file, Memory* memory,
ui::vulkan::VulkanDevice* device, size_t capacity)
: register_file_(register_file), memory_(memory), device_(device) {
transient_buffer_ = std::make_unique<ui::vulkan::CircularBuffer>(
device_,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
capacity, 256);
}
BufferCache::~BufferCache() { Shutdown(); }
VkResult BufferCache::Initialize() {
VkMemoryRequirements pool_reqs;
transient_buffer_->GetBufferMemoryRequirements(&pool_reqs);
gpu_memory_pool_ = device_->AllocateMemory(pool_reqs);
VkResult status = transient_buffer_->Initialize(gpu_memory_pool_, 0);
if (status != VK_SUCCESS) {
return status;
}
// Create a memory allocator for textures.
VmaVulkanFunctions vulkan_funcs = {};
ui::vulkan::FillVMAVulkanFunctions(&vulkan_funcs);
VmaAllocatorCreateInfo alloc_info = {
0, *device_, *device_, 0, 0, nullptr, nullptr, 0, nullptr, &vulkan_funcs,
};
status = vmaCreateAllocator(&alloc_info, &mem_allocator_);
if (status != VK_SUCCESS) {
return status;
}
status = CreateConstantDescriptorSet();
if (status != VK_SUCCESS) {
return status;
}
status = CreateVertexDescriptorPool();
if (status != VK_SUCCESS) {
return status;
}
return VK_SUCCESS;
}
VkResult xe::gpu::vulkan::BufferCache::CreateVertexDescriptorPool() {
VkResult status;
std::vector<VkDescriptorPoolSize> pool_sizes;
pool_sizes.push_back({
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
32 * 16384,
});
vertex_descriptor_pool_ = std::make_unique<ui::vulkan::DescriptorPool>(
*device_, 32 * 16384, pool_sizes);
// 32 storage buffers available to vertex shader.
// TODO(DrChat): In the future, this could hold memexport staging data.
VkDescriptorSetLayoutBinding binding = {
0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
32, VK_SHADER_STAGE_VERTEX_BIT,
nullptr,
};
VkDescriptorSetLayoutCreateInfo layout_info = {
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
nullptr,
0,
1,
&binding,
};
status = vkCreateDescriptorSetLayout(*device_, &layout_info, nullptr,
&vertex_descriptor_set_layout_);
if (status != VK_SUCCESS) {
return status;
}
return VK_SUCCESS;
}
void xe::gpu::vulkan::BufferCache::FreeVertexDescriptorPool() {
vertex_descriptor_pool_.reset();
VK_SAFE_DESTROY(vkDestroyDescriptorSetLayout, *device_,
vertex_descriptor_set_layout_, nullptr);
}
VkResult BufferCache::CreateConstantDescriptorSet() {
VkResult status = VK_SUCCESS;
// Descriptor pool used for all of our cached descriptors.
// In the steady state we don't allocate anything, so these are all manually
// managed.
VkDescriptorPoolCreateInfo transient_descriptor_pool_info;
transient_descriptor_pool_info.sType =
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
transient_descriptor_pool_info.pNext = nullptr;
transient_descriptor_pool_info.flags =
VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
transient_descriptor_pool_info.maxSets = 1;
VkDescriptorPoolSize pool_sizes[1];
pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
pool_sizes[0].descriptorCount = 2;
transient_descriptor_pool_info.poolSizeCount = 1;
transient_descriptor_pool_info.pPoolSizes = pool_sizes;
status = vkCreateDescriptorPool(*device_, &transient_descriptor_pool_info,
nullptr, &constant_descriptor_pool_);
if (status != VK_SUCCESS) {
return status;
}
// Create the descriptor set layout used for our uniform buffer.
// As it is a static binding that uses dynamic offsets during draws we can
// create this once and reuse it forever.
VkDescriptorSetLayoutBinding bindings[2] = {};
// Vertex constants
bindings[0].binding = 0;
bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
bindings[0].descriptorCount = 1;
bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
bindings[0].pImmutableSamplers = nullptr;
// Fragment constants
bindings[1].binding = 1;
bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
bindings[1].descriptorCount = 1;
bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
bindings[1].pImmutableSamplers = nullptr;
VkDescriptorSetLayoutCreateInfo descriptor_set_layout_info = {};
descriptor_set_layout_info.sType =
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
descriptor_set_layout_info.pNext = nullptr;
descriptor_set_layout_info.flags = 0;
descriptor_set_layout_info.bindingCount =
static_cast<uint32_t>(xe::countof(bindings));
descriptor_set_layout_info.pBindings = bindings;
status =
vkCreateDescriptorSetLayout(*device_, &descriptor_set_layout_info,
nullptr, &constant_descriptor_set_layout_);
if (status != VK_SUCCESS) {
return status;
}
// Create the descriptor we'll use for the uniform buffer.
// This is what we hand out to everyone (who then also needs to use our
// offsets).
VkDescriptorSetAllocateInfo set_alloc_info;
set_alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
set_alloc_info.pNext = nullptr;
set_alloc_info.descriptorPool = constant_descriptor_pool_;
set_alloc_info.descriptorSetCount = 1;
set_alloc_info.pSetLayouts = &constant_descriptor_set_layout_;
status = vkAllocateDescriptorSets(*device_, &set_alloc_info,
&constant_descriptor_set_);
if (status != VK_SUCCESS) {
return status;
}
// Initialize descriptor set with our buffers.
VkDescriptorBufferInfo buffer_info;
buffer_info.buffer = transient_buffer_->gpu_buffer();
buffer_info.offset = 0;
buffer_info.range = kConstantRegisterUniformRange;
VkWriteDescriptorSet descriptor_writes[2];
auto& vertex_uniform_binding_write = descriptor_writes[0];
vertex_uniform_binding_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
vertex_uniform_binding_write.pNext = nullptr;
vertex_uniform_binding_write.dstSet = constant_descriptor_set_;
vertex_uniform_binding_write.dstBinding = 0;
vertex_uniform_binding_write.dstArrayElement = 0;
vertex_uniform_binding_write.descriptorCount = 1;
vertex_uniform_binding_write.descriptorType =
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
vertex_uniform_binding_write.pBufferInfo = &buffer_info;
auto& fragment_uniform_binding_write = descriptor_writes[1];
fragment_uniform_binding_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
fragment_uniform_binding_write.pNext = nullptr;
fragment_uniform_binding_write.dstSet = constant_descriptor_set_;
fragment_uniform_binding_write.dstBinding = 1;
fragment_uniform_binding_write.dstArrayElement = 0;
fragment_uniform_binding_write.descriptorCount = 1;
fragment_uniform_binding_write.descriptorType =
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
fragment_uniform_binding_write.pBufferInfo = &buffer_info;
vkUpdateDescriptorSets(*device_, 2, descriptor_writes, 0, nullptr);
return VK_SUCCESS;
}
void BufferCache::FreeConstantDescriptorSet() {
if (constant_descriptor_set_) {
vkFreeDescriptorSets(*device_, constant_descriptor_pool_, 1,
&constant_descriptor_set_);
constant_descriptor_set_ = nullptr;
}
VK_SAFE_DESTROY(vkDestroyDescriptorSetLayout, *device_,
constant_descriptor_set_layout_, nullptr);
VK_SAFE_DESTROY(vkDestroyDescriptorPool, *device_, constant_descriptor_pool_,
nullptr);
}
void BufferCache::Shutdown() {
if (mem_allocator_) {
vmaDestroyAllocator(mem_allocator_);
mem_allocator_ = nullptr;
}
FreeConstantDescriptorSet();
FreeVertexDescriptorPool();
transient_buffer_->Shutdown();
VK_SAFE_DESTROY(vkFreeMemory, *device_, gpu_memory_pool_, nullptr);
}
std::pair<VkDeviceSize, VkDeviceSize> BufferCache::UploadConstantRegisters(
VkCommandBuffer command_buffer,
const Shader::ConstantRegisterMap& vertex_constant_register_map,
const Shader::ConstantRegisterMap& pixel_constant_register_map,
VkFence fence) {
// Fat struct, including all registers:
// struct {
// vec4 float[512];
// uint bool[8];
// uint loop[32];
// };
auto offset = AllocateTransientData(kConstantRegisterUniformRange, fence);
if (offset == VK_WHOLE_SIZE) {
// OOM.
return {VK_WHOLE_SIZE, VK_WHOLE_SIZE};
}
// Copy over all the registers.
const auto& values = register_file_->values;
uint8_t* dest_ptr = transient_buffer_->host_base() + offset;
std::memcpy(dest_ptr, &values[XE_GPU_REG_SHADER_CONSTANT_000_X].f32,
(512 * 4 * 4));
dest_ptr += 512 * 4 * 4;
std::memcpy(dest_ptr, &values[XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031].u32,
8 * 4);
dest_ptr += 8 * 4;
std::memcpy(dest_ptr, &values[XE_GPU_REG_SHADER_CONSTANT_LOOP_00].u32,
32 * 4);
dest_ptr += 32 * 4;
transient_buffer_->Flush(offset, kConstantRegisterUniformRange);
// Append a barrier to the command buffer.
VkBufferMemoryBarrier barrier = {
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
nullptr,
VK_ACCESS_HOST_WRITE_BIT,
VK_ACCESS_UNIFORM_READ_BIT | VK_ACCESS_SHADER_READ_BIT,
VK_QUEUE_FAMILY_IGNORED,
VK_QUEUE_FAMILY_IGNORED,
transient_buffer_->gpu_buffer(),
offset,
kConstantRegisterUniformRange,
};
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 1,
&barrier, 0, nullptr);
return {offset, offset};
// Packed upload code.
// This is not currently supported by the shaders, but would be awesome.
// We should be able to use this for any shader that does not do dynamic
// constant indexing.
#if 0
// Allocate space in the buffer for our data.
auto offset =
AllocateTransientData(constant_register_map.packed_byte_length, fence);
if (offset == VK_WHOLE_SIZE) {
// OOM.
return VK_WHOLE_SIZE;
}
// Run through registers and copy them into the buffer.
// TODO(benvanik): optimize this - it's hit twice every call.
const auto& values = register_file_->values;
uint8_t* dest_ptr =
reinterpret_cast<uint8_t*>(transient_buffer_data_) + offset;
for (int i = 0; i < 4; ++i) {
auto piece = constant_register_map.float_bitmap[i];
if (!piece) {
continue;
}
for (int j = 0, sh = 0; j < 64; ++j, sh << 1) {
if (piece & sh) {
xe::copy_128_aligned(
dest_ptr,
&values[XE_GPU_REG_SHADER_CONSTANT_000_X + i * 64 + j].f32, 1);
dest_ptr += 16;
}
}
}
for (int i = 0; i < 32; ++i) {
if (constant_register_map.loop_bitmap & (1 << i)) {
xe::store<uint32_t>(dest_ptr,
values[XE_GPU_REG_SHADER_CONSTANT_LOOP_00 + i].u32);
dest_ptr += 4;
}
}
for (int i = 0; i < 8; ++i) {
if (constant_register_map.bool_bitmap[i]) {
xe::store<uint32_t>(
dest_ptr, values[XE_GPU_REG_SHADER_CONSTANT_BOOL_000_031 + i].u32);
dest_ptr += 4;
}
}
return offset;
#endif // 0
}
std::pair<VkBuffer, VkDeviceSize> BufferCache::UploadIndexBuffer(
VkCommandBuffer command_buffer, uint32_t source_addr,
uint32_t source_length, xenos::IndexFormat format, VkFence fence) {
// Allocate space in the buffer for our data.
auto offset = AllocateTransientData(source_length, fence);
if (offset == VK_WHOLE_SIZE) {
// OOM.
return {nullptr, VK_WHOLE_SIZE};
}
const void* source_ptr = memory_->TranslatePhysical(source_addr);
uint32_t prim_reset_index =
register_file_->values[XE_GPU_REG_VGT_MULTI_PRIM_IB_RESET_INDX].u32;
bool prim_reset_enabled =
!!(register_file_->values[XE_GPU_REG_PA_SU_SC_MODE_CNTL].u32 & (1 << 21));
// Copy data into the buffer. If primitive reset is enabled, translate any
// primitive reset indices to something Vulkan understands.
// TODO(benvanik): memcpy then use compute shaders to swap?
if (prim_reset_enabled) {
if (format == xenos::IndexFormat::kInt16) {
// Endian::k8in16, swap half-words.
copy_cmp_swap_16_unaligned(
transient_buffer_->host_base() + offset, source_ptr,
static_cast<uint16_t>(prim_reset_index), source_length / 2);
} else if (format == xenos::IndexFormat::kInt32) {
// Endian::k8in32, swap words.
copy_cmp_swap_32_unaligned(transient_buffer_->host_base() + offset,
source_ptr, prim_reset_index,
source_length / 4);
}
} else {
if (format == xenos::IndexFormat::kInt16) {
// Endian::k8in16, swap half-words.
xe::copy_and_swap_16_unaligned(transient_buffer_->host_base() + offset,
source_ptr, source_length / 2);
} else if (format == xenos::IndexFormat::kInt32) {
// Endian::k8in32, swap words.
xe::copy_and_swap_32_unaligned(transient_buffer_->host_base() + offset,
source_ptr, source_length / 4);
}
}
transient_buffer_->Flush(offset, source_length);
// Append a barrier to the command buffer.
VkBufferMemoryBarrier barrier = {
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
nullptr,
VK_ACCESS_HOST_WRITE_BIT,
VK_ACCESS_INDEX_READ_BIT,
VK_QUEUE_FAMILY_IGNORED,
VK_QUEUE_FAMILY_IGNORED,
transient_buffer_->gpu_buffer(),
offset,
source_length,
};
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT,
VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0, 0, nullptr, 1,
&barrier, 0, nullptr);
return {transient_buffer_->gpu_buffer(), offset};
}
std::pair<VkBuffer, VkDeviceSize> BufferCache::UploadVertexBuffer(
VkCommandBuffer command_buffer, uint32_t source_addr,
uint32_t source_length, xenos::Endian endian, VkFence fence) {
auto offset = FindCachedTransientData(source_addr, source_length);
if (offset != VK_WHOLE_SIZE) {
return {transient_buffer_->gpu_buffer(), offset};
}
// Slow path :)
// Expand the region up to the allocation boundary
auto physical_heap = memory_->GetPhysicalHeap();
uint32_t upload_base = source_addr;
uint32_t upload_size = source_length;
// Ping the memory subsystem for allocation size.
// TODO(DrChat): Artifacting occurring in GripShift with this enabled.
// physical_heap->QueryBaseAndSize(&upload_base, &upload_size);
assert(upload_base <= source_addr);
uint32_t source_offset = source_addr - upload_base;
// Allocate space in the buffer for our data.
offset = AllocateTransientData(upload_size, fence);
if (offset == VK_WHOLE_SIZE) {
// OOM.
XELOGW(
"Failed to allocate transient data for vertex buffer! Wanted to "
"allocate {} bytes.",
upload_size);
return {nullptr, VK_WHOLE_SIZE};
}
const void* upload_ptr = memory_->TranslatePhysical(upload_base);
// Copy data into the buffer.
// TODO(benvanik): memcpy then use compute shaders to swap?
if (endian == xenos::Endian::k8in32) {
// Endian::k8in32, swap words.
xe::copy_and_swap_32_unaligned(transient_buffer_->host_base() + offset,
upload_ptr, source_length / 4);
} else if (endian == xenos::Endian::k16in32) {
xe::copy_and_swap_16_in_32_unaligned(
transient_buffer_->host_base() + offset, upload_ptr, source_length / 4);
} else {
assert_always();
}
transient_buffer_->Flush(offset, upload_size);
// Append a barrier to the command buffer.
VkBufferMemoryBarrier barrier = {
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
nullptr,
VK_ACCESS_HOST_WRITE_BIT,
VK_ACCESS_SHADER_READ_BIT,
VK_QUEUE_FAMILY_IGNORED,
VK_QUEUE_FAMILY_IGNORED,
transient_buffer_->gpu_buffer(),
offset,
upload_size,
};
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_HOST_BIT,
VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, 0, 0, nullptr, 1,
&barrier, 0, nullptr);
CacheTransientData(upload_base, upload_size, offset);
return {transient_buffer_->gpu_buffer(), offset + source_offset};
}
void BufferCache::HashVertexBindings(
XXH64_state_t* hash_state,
const std::vector<Shader::VertexBinding>& vertex_bindings) {
auto& regs = *register_file_;
for (const auto& vertex_binding : vertex_bindings) {
#if 0
XXH64_update(hash_state, &vertex_binding.binding_index, sizeof(vertex_binding.binding_index));
XXH64_update(hash_state, &vertex_binding.fetch_constant, sizeof(vertex_binding.fetch_constant));
XXH64_update(hash_state, &vertex_binding.stride_words, sizeof(vertex_binding.stride_words));
#endif
int r = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 +
(vertex_binding.fetch_constant / 3) * 6;
const auto group = reinterpret_cast<xe_gpu_fetch_group_t*>(&regs.values[r]);
switch (vertex_binding.fetch_constant % 3) {
case 0: {
auto& fetch = group->vertex_fetch_0;
XXH64_update(hash_state, &fetch, sizeof(fetch));
} break;
case 1: {
auto& fetch = group->vertex_fetch_1;
XXH64_update(hash_state, &fetch, sizeof(fetch));
} break;
case 2: {
auto& fetch = group->vertex_fetch_2;
XXH64_update(hash_state, &fetch, sizeof(fetch));
} break;
}
}
}
VkDescriptorSet BufferCache::PrepareVertexSet(
VkCommandBuffer command_buffer, VkFence fence,
const std::vector<Shader::VertexBinding>& vertex_bindings) {
// (quickly) Generate a hash.
XXH64_state_t hash_state;
XXH64_reset(&hash_state, 0);
// (quickly) Generate a hash.
HashVertexBindings(&hash_state, vertex_bindings);
uint64_t hash = XXH64_digest(&hash_state);
for (auto it = vertex_sets_.find(hash); it != vertex_sets_.end(); ++it) {
// TODO(DrChat): We need to compare the bindings and ensure they're equal.
return it->second;
}
if (!vertex_descriptor_pool_->has_open_batch()) {
vertex_descriptor_pool_->BeginBatch(fence);
}
VkDescriptorSet set =
vertex_descriptor_pool_->AcquireEntry(vertex_descriptor_set_layout_);
if (!set) {
return nullptr;
}
// TODO(DrChat): Define magic number 32 as a constant somewhere.
VkDescriptorBufferInfo buffer_infos[32] = {};
VkWriteDescriptorSet descriptor_write = {
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
nullptr,
set,
0,
0,
0,
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
nullptr,
buffer_infos,
nullptr,
};
auto& regs = *register_file_;
for (const auto& vertex_binding : vertex_bindings) {
int r = XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0 +
(vertex_binding.fetch_constant / 3) * 6;
const auto group = reinterpret_cast<xe_gpu_fetch_group_t*>(&regs.values[r]);
const xe_gpu_vertex_fetch_t* fetch = nullptr;
switch (vertex_binding.fetch_constant % 3) {
case 0:
fetch = &group->vertex_fetch_0;
break;
case 1:
fetch = &group->vertex_fetch_1;
break;
case 2:
fetch = &group->vertex_fetch_2;
break;
}
// TODO(DrChat): Some games use type kInvalidTexture (with no data).
switch (fetch->type) {
case xenos::FetchConstantType::kVertex:
break;
case xenos::FetchConstantType::kInvalidVertex:
if (cvars::gpu_allow_invalid_fetch_constants) {
break;
}
XELOGW(
"Vertex fetch constant {} ({:08X} {:08X}) has \"invalid\" type! "
"This "
"is incorrect behavior, but you can try bypassing this by "
"launching Xenia with --gpu_allow_invalid_fetch_constants=true.",
vertex_binding.fetch_constant, fetch->dword_0, fetch->dword_1);
return nullptr;
default:
XELOGW(
"Vertex fetch constant {} ({:08X} {:08X}) is completely invalid!",
vertex_binding.fetch_constant, fetch->dword_0, fetch->dword_1);
return nullptr;
}
// TODO(benvanik): compute based on indices or vertex count.
// THIS CAN BE MASSIVELY INCORRECT (too large).
// This may not be possible (with indexed vfetch).
uint32_t source_length = fetch->size * 4;
uint32_t physical_address = fetch->address << 2;
// TODO(DrChat): This needs to be put in gpu::CommandProcessor
// trace_writer_.WriteMemoryRead(physical_address, source_length);
// Upload (or get a cached copy of) the buffer.
auto buffer_ref = UploadVertexBuffer(command_buffer, physical_address,
source_length, fetch->endian, fence);
if (buffer_ref.second == VK_WHOLE_SIZE) {
// Failed to upload buffer.
XELOGW("Failed to upload vertex buffer!");
return nullptr;
}
// Stash the buffer reference for our bulk bind at the end.
buffer_infos[descriptor_write.descriptorCount++] = {
buffer_ref.first,
buffer_ref.second,
source_length,
};
}
vkUpdateDescriptorSets(*device_, 1, &descriptor_write, 0, nullptr);
vertex_sets_[hash] = set;
return set;
}
VkDeviceSize BufferCache::AllocateTransientData(VkDeviceSize length,
VkFence fence) {
// Try fast path (if we have space).
VkDeviceSize offset = TryAllocateTransientData(length, fence);
if (offset != VK_WHOLE_SIZE) {
return offset;
}
// Ran out of easy allocations.
// Try consuming fences before we panic.
transient_buffer_->Scavenge();
// Try again. It may still fail if we didn't get enough space back.
offset = TryAllocateTransientData(length, fence);
return offset;
}
VkDeviceSize BufferCache::TryAllocateTransientData(VkDeviceSize length,
VkFence fence) {
auto alloc = transient_buffer_->Acquire(length, fence);
if (alloc) {
return alloc->offset;
}
// No more space.
return VK_WHOLE_SIZE;
}
VkDeviceSize BufferCache::FindCachedTransientData(uint32_t guest_address,
uint32_t guest_length) {
if (transient_cache_.empty()) {
// Short-circuit exit.
return VK_WHOLE_SIZE;
}
// Find the first element > guest_address
auto it = transient_cache_.upper_bound(guest_address);
if (it != transient_cache_.begin()) {
// it = first element <= guest_address
--it;
if ((it->first + it->second.first) >= (guest_address + guest_length)) {
// This data is contained within some existing transient data.
auto source_offset = static_cast<VkDeviceSize>(guest_address - it->first);
return it->second.second + source_offset;
}
}
return VK_WHOLE_SIZE;
}
void BufferCache::CacheTransientData(uint32_t guest_address,
uint32_t guest_length,
VkDeviceSize offset) {
transient_cache_[guest_address] = {guest_length, offset};
// Erase any entries contained within
auto it = transient_cache_.upper_bound(guest_address);
while (it != transient_cache_.end()) {
if ((guest_address + guest_length) >= (it->first + it->second.first)) {
it = transient_cache_.erase(it);
} else {
break;
}
}
}
void BufferCache::Flush(VkCommandBuffer command_buffer) {
// If we are flushing a big enough chunk queue up an event.
// We don't want to do this for everything but often enough so that we won't
// run out of space.
if (true) {
// VkEvent finish_event;
// vkCmdSetEvent(cmd_buffer, finish_event,
// VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
}
// Flush memory.
// TODO(benvanik): subrange.
VkMappedMemoryRange dirty_range;
dirty_range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
dirty_range.pNext = nullptr;
dirty_range.memory = transient_buffer_->gpu_memory();
dirty_range.offset = 0;
dirty_range.size = transient_buffer_->capacity();
vkFlushMappedMemoryRanges(*device_, 1, &dirty_range);
}
void BufferCache::InvalidateCache() {
// Called by VulkanCommandProcessor::MakeCoherent()
// Discard everything?
transient_cache_.clear();
}
void BufferCache::ClearCache() { transient_cache_.clear(); }
void BufferCache::Scavenge() {
SCOPE_profile_cpu_f("gpu");
transient_cache_.clear();
transient_buffer_->Scavenge();
// TODO(DrChat): These could persist across frames, we just need a smart way
// to delete unused ones.
vertex_sets_.clear();
if (vertex_descriptor_pool_->has_open_batch()) {
vertex_descriptor_pool_->EndBatch();
}
vertex_descriptor_pool_->Scavenge();
}
} // namespace vulkan
} // namespace gpu
} // namespace xe

View File

@@ -1,177 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_GPU_VULKAN_BUFFER_CACHE_H_
#define XENIA_GPU_VULKAN_BUFFER_CACHE_H_
#include "xenia/gpu/register_file.h"
#include "xenia/gpu/shader.h"
#include "xenia/gpu/xenos.h"
#include "xenia/memory.h"
#include "xenia/ui/vulkan/circular_buffer.h"
#include "xenia/ui/vulkan/fenced_pools.h"
#include "xenia/ui/vulkan/vulkan.h"
#include "xenia/ui/vulkan/vulkan_device.h"
#include "third_party/vulkan/vk_mem_alloc.h"
#include "third_party/xxhash/xxhash.h"
#include <map>
#include <unordered_map>
namespace xe {
namespace gpu {
namespace vulkan {
// Efficiently manages buffers of various kinds.
// Used primarily for uploading index and vertex data from guest memory and
// transient data like shader constants.
class BufferCache {
public:
BufferCache(RegisterFile* register_file, Memory* memory,
ui::vulkan::VulkanDevice* device, size_t capacity);
~BufferCache();
VkResult Initialize();
void Shutdown();
// Descriptor set containing the dynamic uniform buffer used for constant
// uploads. Used in conjunction with a dynamic offset returned by
// UploadConstantRegisters.
// The set contains two bindings:
// binding = 0: for use in vertex shaders
// binding = 1: for use in fragment shaders
VkDescriptorSet constant_descriptor_set() const {
return constant_descriptor_set_;
}
VkDescriptorSetLayout constant_descriptor_set_layout() const {
return constant_descriptor_set_layout_;
}
// Descriptor set containing vertex buffers stored in storage buffers.
// This set contains one binding with an array of 32 storage buffers.
VkDescriptorSetLayout vertex_descriptor_set_layout() const {
return vertex_descriptor_set_layout_;
}
// Uploads the constants specified in the register maps to the transient
// uniform storage buffer.
// The registers are tightly packed in order as [floats, ints, bools].
// Returns an offset that can be used with the transient_descriptor_set or
// VK_WHOLE_SIZE if the constants could not be uploaded (OOM).
// The returned offsets may alias.
std::pair<VkDeviceSize, VkDeviceSize> UploadConstantRegisters(
VkCommandBuffer command_buffer,
const Shader::ConstantRegisterMap& vertex_constant_register_map,
const Shader::ConstantRegisterMap& pixel_constant_register_map,
VkFence fence);
// Uploads index buffer data from guest memory, possibly eliding with
// recently uploaded data or cached copies.
// Returns a buffer and offset that can be used with vkCmdBindIndexBuffer.
// Size will be VK_WHOLE_SIZE if the data could not be uploaded (OOM).
std::pair<VkBuffer, VkDeviceSize> UploadIndexBuffer(
VkCommandBuffer command_buffer, uint32_t source_addr,
uint32_t source_length, xenos::IndexFormat format, VkFence fence);
// Uploads vertex buffer data from guest memory, possibly eliding with
// recently uploaded data or cached copies.
// Returns a buffer and offset that can be used with vkCmdBindVertexBuffers.
// Size will be VK_WHOLE_SIZE if the data could not be uploaded (OOM).
std::pair<VkBuffer, VkDeviceSize> UploadVertexBuffer(
VkCommandBuffer command_buffer, uint32_t source_addr,
uint32_t source_length, xenos::Endian endian, VkFence fence);
// Prepares and returns a vertex descriptor set.
VkDescriptorSet PrepareVertexSet(
VkCommandBuffer setup_buffer, VkFence fence,
const std::vector<Shader::VertexBinding>& vertex_bindings);
// Flushes all pending data to the GPU.
// Until this is called the GPU is not guaranteed to see any data.
// The given command buffer will be used to queue up events so that the
// cache can determine when data has been consumed.
void Flush(VkCommandBuffer command_buffer);
// Marks the cache as potentially invalid.
// This is not as strong as ClearCache and is a hint that any and all data
// should be verified before being reused.
void InvalidateCache();
// Clears all cached content and prevents future elision with pending data.
void ClearCache();
// Wipes all data no longer needed.
void Scavenge();
private:
// This represents an uploaded vertex buffer.
struct VertexBuffer {
uint32_t guest_address;
uint32_t size;
VmaAllocation alloc;
VmaAllocationInfo alloc_info;
};
VkResult CreateVertexDescriptorPool();
void FreeVertexDescriptorPool();
VkResult CreateConstantDescriptorSet();
void FreeConstantDescriptorSet();
void HashVertexBindings(
XXH64_state_t* hash_state,
const std::vector<Shader::VertexBinding>& vertex_bindings);
// Allocates a block of memory in the transient buffer.
// When memory is not available fences are checked and space is reclaimed.
// Returns VK_WHOLE_SIZE if requested amount of memory is not available.
VkDeviceSize AllocateTransientData(VkDeviceSize length, VkFence fence);
// Tries to allocate a block of memory in the transient buffer.
// Returns VK_WHOLE_SIZE if requested amount of memory is not available.
VkDeviceSize TryAllocateTransientData(VkDeviceSize length, VkFence fence);
// Finds a block of data in the transient buffer sourced from the specified
// guest address and length.
VkDeviceSize FindCachedTransientData(uint32_t guest_address,
uint32_t guest_length);
// Adds a block of data to the frame cache.
void CacheTransientData(uint32_t guest_address, uint32_t guest_length,
VkDeviceSize offset);
RegisterFile* register_file_ = nullptr;
Memory* memory_ = nullptr;
ui::vulkan::VulkanDevice* device_ = nullptr;
VkDeviceMemory gpu_memory_pool_ = nullptr;
VmaAllocator mem_allocator_ = nullptr;
// Staging ringbuffer we cycle through fast. Used for data we don't
// plan on keeping past the current frame.
std::unique_ptr<ui::vulkan::CircularBuffer> transient_buffer_ = nullptr;
std::map<uint32_t, std::pair<uint32_t, VkDeviceSize>> transient_cache_;
// Vertex buffer descriptors
std::unique_ptr<ui::vulkan::DescriptorPool> vertex_descriptor_pool_ = nullptr;
VkDescriptorSetLayout vertex_descriptor_set_layout_ = nullptr;
// Current frame vertex sets.
std::unordered_map<uint64_t, VkDescriptorSet> vertex_sets_;
// Descriptor set used to hold vertex/pixel shader float constants
VkDescriptorPool constant_descriptor_pool_ = nullptr;
VkDescriptorSetLayout constant_descriptor_set_layout_ = nullptr;
VkDescriptorSet constant_descriptor_set_ = nullptr;
};
} // namespace vulkan
} // namespace gpu
} // namespace xe
#endif // XENIA_GPU_VULKAN_BUFFER_CACHE_H_

File diff suppressed because it is too large Load Diff

View File

@@ -1,311 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_GPU_VULKAN_PIPELINE_CACHE_H_
#define XENIA_GPU_VULKAN_PIPELINE_CACHE_H_
#include <unordered_map>
#include "third_party/xxhash/xxhash.h"
#include "xenia/gpu/register_file.h"
#include "xenia/gpu/spirv_shader_translator.h"
#include "xenia/gpu/vulkan/render_cache.h"
#include "xenia/gpu/vulkan/vulkan_shader.h"
#include "xenia/gpu/xenos.h"
#include "xenia/ui/spirv/spirv_disassembler.h"
#include "xenia/ui/vulkan/vulkan.h"
#include "xenia/ui/vulkan/vulkan_device.h"
namespace xe {
namespace gpu {
namespace vulkan {
// Configures and caches pipelines based on render state.
// This is responsible for properly setting all state required for a draw
// including shaders, various blend/etc options, and input configuration.
class PipelineCache {
public:
enum class UpdateStatus {
kCompatible,
kMismatch,
kError,
};
PipelineCache(RegisterFile* register_file, ui::vulkan::VulkanDevice* device);
~PipelineCache();
VkResult Initialize(VkDescriptorSetLayout uniform_descriptor_set_layout,
VkDescriptorSetLayout texture_descriptor_set_layout,
VkDescriptorSetLayout vertex_descriptor_set_layout);
void Shutdown();
// Loads a shader from the cache, possibly translating it.
VulkanShader* LoadShader(xenos::ShaderType shader_type,
uint32_t guest_address, const uint32_t* host_address,
uint32_t dword_count);
// Configures a pipeline using the current render state and the given render
// pass. If a previously available pipeline is available it will be used,
// otherwise a new one may be created. Any state that can be set dynamically
// in the command buffer is issued at this time.
// Returns whether the pipeline could be successfully created.
UpdateStatus ConfigurePipeline(VkCommandBuffer command_buffer,
const RenderState* render_state,
VulkanShader* vertex_shader,
VulkanShader* pixel_shader,
xenos::PrimitiveType primitive_type,
VkPipeline* pipeline_out);
// Sets required dynamic state on the command buffer.
// Only state that has changed since the last call will be set unless
// full_update is true.
bool SetDynamicState(VkCommandBuffer command_buffer, bool full_update);
// Pipeline layout shared by all pipelines.
VkPipelineLayout pipeline_layout() const { return pipeline_layout_; }
// Clears all cached content.
void ClearCache();
private:
// Creates or retrieves an existing pipeline for the currently configured
// state.
VkPipeline GetPipeline(const RenderState* render_state, uint64_t hash_key);
bool TranslateShader(VulkanShader* shader, reg::SQ_PROGRAM_CNTL cntl);
void DumpShaderDisasmAMD(VkPipeline pipeline);
void DumpShaderDisasmNV(const VkGraphicsPipelineCreateInfo& info);
// Gets a geometry shader used to emulate the given primitive type.
// Returns nullptr if the primitive doesn't need to be emulated.
VkShaderModule GetGeometryShader(xenos::PrimitiveType primitive_type,
bool is_line_mode);
RegisterFile* register_file_ = nullptr;
ui::vulkan::VulkanDevice* device_ = nullptr;
// Reusable shader translator.
std::unique_ptr<ShaderTranslator> shader_translator_ = nullptr;
// Disassembler used to get the SPIRV disasm. Only used in debug.
xe::ui::spirv::SpirvDisassembler disassembler_;
// All loaded shaders mapped by their guest hash key.
std::unordered_map<uint64_t, VulkanShader*> shader_map_;
// Vulkan pipeline cache, which in theory helps us out.
// This can be serialized to disk and reused, if we want.
VkPipelineCache pipeline_cache_ = nullptr;
// Layout used for all pipelines describing our uniforms, textures, and push
// constants.
VkPipelineLayout pipeline_layout_ = nullptr;
// Shared geometry shaders.
struct {
VkShaderModule line_quad_list;
VkShaderModule point_list;
VkShaderModule quad_list;
VkShaderModule rect_list;
} geometry_shaders_;
// Shared dummy pixel shader.
VkShaderModule dummy_pixel_shader_;
// Hash state used to incrementally produce pipeline hashes during update.
// By the time the full update pass has run the hash will represent the
// current state in a way that can uniquely identify the produced VkPipeline.
XXH64_state_t hash_state_;
// All previously generated pipelines mapped by hash.
std::unordered_map<uint64_t, VkPipeline> cached_pipelines_;
// Previously used pipeline. This matches our current state settings
// and allows us to quickly(ish) reuse the pipeline if no registers have
// changed.
VkPipeline current_pipeline_ = nullptr;
private:
UpdateStatus UpdateState(VulkanShader* vertex_shader,
VulkanShader* pixel_shader,
xenos::PrimitiveType primitive_type);
UpdateStatus UpdateRenderTargetState();
UpdateStatus UpdateShaderStages(VulkanShader* vertex_shader,
VulkanShader* pixel_shader,
xenos::PrimitiveType primitive_type);
UpdateStatus UpdateVertexInputState(VulkanShader* vertex_shader);
UpdateStatus UpdateInputAssemblyState(xenos::PrimitiveType primitive_type);
UpdateStatus UpdateViewportState();
UpdateStatus UpdateRasterizationState(xenos::PrimitiveType primitive_type);
UpdateStatus UpdateMultisampleState();
UpdateStatus UpdateDepthStencilState();
UpdateStatus UpdateColorBlendState();
bool SetShadowRegister(uint32_t* dest, uint32_t register_name);
bool SetShadowRegister(float* dest, uint32_t register_name);
bool SetShadowRegisterArray(uint32_t* dest, uint32_t num,
uint32_t register_name);
struct UpdateRenderTargetsRegisters {
uint32_t rb_modecontrol;
reg::RB_SURFACE_INFO rb_surface_info;
reg::RB_COLOR_INFO rb_color_info;
reg::RB_DEPTH_INFO rb_depth_info;
reg::RB_COLOR_INFO rb_color1_info;
reg::RB_COLOR_INFO rb_color2_info;
reg::RB_COLOR_INFO rb_color3_info;
uint32_t rb_color_mask;
uint32_t rb_depthcontrol;
uint32_t rb_stencilrefmask;
UpdateRenderTargetsRegisters() { Reset(); }
void Reset() { std::memset(this, 0, sizeof(*this)); }
} update_render_targets_regs_;
struct UpdateShaderStagesRegisters {
xenos::PrimitiveType primitive_type;
uint32_t pa_su_sc_mode_cntl;
reg::SQ_PROGRAM_CNTL sq_program_cntl;
VulkanShader* vertex_shader;
VulkanShader* pixel_shader;
UpdateShaderStagesRegisters() { Reset(); }
void Reset() { std::memset(this, 0, sizeof(*this)); }
} update_shader_stages_regs_;
VkPipelineShaderStageCreateInfo update_shader_stages_info_[3];
uint32_t update_shader_stages_stage_count_ = 0;
struct UpdateVertexInputStateRegisters {
VulkanShader* vertex_shader;
UpdateVertexInputStateRegisters() { Reset(); }
void Reset() { std::memset(this, 0, sizeof(*this)); }
} update_vertex_input_state_regs_;
VkPipelineVertexInputStateCreateInfo update_vertex_input_state_info_;
VkVertexInputBindingDescription update_vertex_input_state_binding_descrs_[32];
VkVertexInputAttributeDescription
update_vertex_input_state_attrib_descrs_[96];
struct UpdateInputAssemblyStateRegisters {
xenos::PrimitiveType primitive_type;
uint32_t pa_su_sc_mode_cntl;
uint32_t multi_prim_ib_reset_index;
UpdateInputAssemblyStateRegisters() { Reset(); }
void Reset() { std::memset(this, 0, sizeof(*this)); }
} update_input_assembly_state_regs_;
VkPipelineInputAssemblyStateCreateInfo update_input_assembly_state_info_;
struct UpdateViewportStateRegisters {
// uint32_t pa_cl_clip_cntl;
uint32_t rb_surface_info;
uint32_t pa_cl_vte_cntl;
uint32_t pa_su_sc_mode_cntl;
uint32_t pa_sc_window_offset;
uint32_t pa_sc_window_scissor_tl;
uint32_t pa_sc_window_scissor_br;
float pa_cl_vport_xoffset;
float pa_cl_vport_yoffset;
float pa_cl_vport_zoffset;
float pa_cl_vport_xscale;
float pa_cl_vport_yscale;
float pa_cl_vport_zscale;
UpdateViewportStateRegisters() { Reset(); }
void Reset() { std::memset(this, 0, sizeof(*this)); }
} update_viewport_state_regs_;
VkPipelineViewportStateCreateInfo update_viewport_state_info_;
struct UpdateRasterizationStateRegisters {
xenos::PrimitiveType primitive_type;
uint32_t pa_cl_clip_cntl;
uint32_t pa_su_sc_mode_cntl;
uint32_t pa_sc_screen_scissor_tl;
uint32_t pa_sc_screen_scissor_br;
uint32_t pa_sc_viz_query;
uint32_t pa_su_poly_offset_enable;
uint32_t multi_prim_ib_reset_index;
UpdateRasterizationStateRegisters() { Reset(); }
void Reset() { std::memset(this, 0, sizeof(*this)); }
} update_rasterization_state_regs_;
VkPipelineRasterizationStateCreateInfo update_rasterization_state_info_;
struct UpdateMultisampleStateeRegisters {
uint32_t pa_sc_aa_config;
uint32_t pa_su_sc_mode_cntl;
uint32_t rb_surface_info;
UpdateMultisampleStateeRegisters() { Reset(); }
void Reset() { std::memset(this, 0, sizeof(*this)); }
} update_multisample_state_regs_;
VkPipelineMultisampleStateCreateInfo update_multisample_state_info_;
struct UpdateDepthStencilStateRegisters {
uint32_t rb_depthcontrol;
uint32_t rb_stencilrefmask;
UpdateDepthStencilStateRegisters() { Reset(); }
void Reset() { std::memset(this, 0, sizeof(*this)); }
} update_depth_stencil_state_regs_;
VkPipelineDepthStencilStateCreateInfo update_depth_stencil_state_info_;
struct UpdateColorBlendStateRegisters {
uint32_t rb_color_mask;
uint32_t rb_blendcontrol[4];
uint32_t rb_modecontrol;
UpdateColorBlendStateRegisters() { Reset(); }
void Reset() { std::memset(this, 0, sizeof(*this)); }
} update_color_blend_state_regs_;
VkPipelineColorBlendStateCreateInfo update_color_blend_state_info_;
VkPipelineColorBlendAttachmentState update_color_blend_attachment_states_[4];
struct SetDynamicStateRegisters {
uint32_t pa_sc_window_offset;
uint32_t pa_su_sc_mode_cntl;
uint32_t pa_sc_window_scissor_tl;
uint32_t pa_sc_window_scissor_br;
uint32_t rb_surface_info;
uint32_t pa_su_sc_vtx_cntl;
// Bias is in Vulkan units because depth format may potentially effect it.
float pa_su_poly_offset_scale;
float pa_su_poly_offset_offset;
uint32_t pa_cl_vte_cntl;
float pa_cl_vport_xoffset;
float pa_cl_vport_yoffset;
float pa_cl_vport_zoffset;
float pa_cl_vport_xscale;
float pa_cl_vport_yscale;
float pa_cl_vport_zscale;
float rb_blend_rgba[4];
uint32_t rb_stencilrefmask;
reg::SQ_PROGRAM_CNTL sq_program_cntl;
uint32_t sq_context_misc;
uint32_t rb_colorcontrol;
reg::RB_COLOR_INFO rb_color_info;
reg::RB_COLOR_INFO rb_color1_info;
reg::RB_COLOR_INFO rb_color2_info;
reg::RB_COLOR_INFO rb_color3_info;
float rb_alpha_ref;
uint32_t pa_su_point_size;
SetDynamicStateRegisters() { Reset(); }
void Reset() { std::memset(this, 0, sizeof(*this)); }
} set_dynamic_state_registers_;
};
} // namespace vulkan
} // namespace gpu
} // namespace xe
#endif // XENIA_GPU_VULKAN_PIPELINE_CACHE_H_

View File

@@ -8,146 +8,13 @@ project("xenia-gpu-vulkan")
language("C++")
links({
"fmt",
"volk",
"xenia-base",
"xenia-gpu",
"xenia-ui",
"xenia-ui-spirv",
"xenia-ui-vulkan",
"xxhash",
})
defines({
})
local_platform_files()
files({
"shaders/bin/*.h",
"../shaders/bytecode/vulkan_spirv/*.h",
})
-- TODO(benvanik): kill this and move to the debugger UI.
group("src")
project("xenia-gpu-vulkan-trace-viewer")
uuid("86a1dddc-a26a-4885-8c55-cf745225d93e")
kind("WindowedApp")
language("C++")
links({
"aes_128",
"capstone",
"fmt",
"glslang-spirv",
"imgui",
"libavcodec",
"libavutil",
"mspack",
"snappy",
"spirv-tools",
"volk",
"xenia-apu",
"xenia-apu-nop",
"xenia-base",
"xenia-core",
"xenia-cpu",
"xenia-cpu-backend-x64",
"xenia-gpu",
"xenia-gpu-vulkan",
"xenia-hid",
"xenia-hid-nop",
"xenia-kernel",
"xenia-ui",
"xenia-ui-spirv",
"xenia-ui-vulkan",
"xenia-vfs",
"xxhash",
})
defines({
})
files({
"vulkan_trace_viewer_main.cc",
"../../base/main_"..platform_suffix..".cc",
})
filter("platforms:Linux")
links({
"X11",
"xcb",
"X11-xcb",
"GL",
"vulkan",
})
filter("platforms:Windows")
links({
"xenia-apu-xaudio2",
"xenia-hid-winkey",
"xenia-hid-xinput",
})
-- Only create the .user file if it doesn't already exist.
local user_file = project_root.."/build/xenia-gpu-vulkan-trace-viewer.vcxproj.user"
if not os.isfile(user_file) then
debugdir(project_root)
debugargs({
"2>&1",
"1>scratch/stdout-trace-viewer.txt",
})
end
group("src")
project("xenia-gpu-vulkan-trace-dump")
uuid("0dd0dd1c-b321-494d-ab9a-6c062f0c65cc")
kind("ConsoleApp")
language("C++")
links({
"aes_128",
"capstone",
"fmt",
"glslang-spirv",
"imgui",
"libavcodec",
"libavutil",
"mspack",
"snappy",
"spirv-tools",
"volk",
"xenia-apu",
"xenia-apu-nop",
"xenia-base",
"xenia-core",
"xenia-cpu",
"xenia-cpu-backend-x64",
"xenia-gpu",
"xenia-gpu-vulkan",
"xenia-hid",
"xenia-hid-nop",
"xenia-kernel",
"xenia-ui",
"xenia-ui-spirv",
"xenia-ui-vulkan",
"xenia-vfs",
"xxhash",
})
defines({
})
files({
"vulkan_trace_dump_main.cc",
"../../base/main_"..platform_suffix..".cc",
})
filter("platforms:Linux")
links({
"X11",
"xcb",
"X11-xcb",
"GL",
"vulkan",
})
filter("platforms:Windows")
-- Only create the .user file if it doesn't already exist.
local user_file = project_root.."/build/xenia-gpu-vulkan-trace-dump.vcxproj.user"
if not os.isfile(user_file) then
debugdir(project_root)
debugargs({
"2>&1",
"1>scratch/stdout-trace-dump.txt",
})
end

File diff suppressed because it is too large Load Diff

View File

@@ -1,406 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_GPU_VULKAN_RENDER_CACHE_H_
#define XENIA_GPU_VULKAN_RENDER_CACHE_H_
#include "xenia/gpu/register_file.h"
#include "xenia/gpu/registers.h"
#include "xenia/gpu/shader.h"
#include "xenia/gpu/texture_info.h"
#include "xenia/gpu/vulkan/vulkan_shader.h"
#include "xenia/gpu/xenos.h"
#include "xenia/ui/vulkan/vulkan.h"
#include "xenia/ui/vulkan/vulkan_device.h"
namespace xe {
namespace gpu {
namespace vulkan {
// TODO(benvanik): make public API?
class CachedTileView;
class CachedFramebuffer;
class CachedRenderPass;
// Uniquely identifies EDRAM tiles.
struct TileViewKey {
// Offset into EDRAM in 5120b tiles.
uint16_t tile_offset;
// Tile width of the view in base 80x16 tiles.
uint16_t tile_width;
// Tile height of the view in base 80x16 tiles.
uint16_t tile_height;
// 1 if format is ColorRenderTargetFormat, else DepthRenderTargetFormat.
uint16_t color_or_depth : 1;
// Surface MSAA samples
uint16_t msaa_samples : 2;
// Either ColorRenderTargetFormat or DepthRenderTargetFormat.
uint16_t edram_format : 13;
};
static_assert(sizeof(TileViewKey) == 8, "Key must be tightly packed");
// Cached view representing EDRAM memory.
// TODO(benvanik): reuse VkImage's with multiple VkViews for compatible
// formats?
class CachedTileView {
public:
// Key identifying the view in the cache.
TileViewKey key;
// Image
VkImage image = nullptr;
// Simple view on the image matching the format.
VkImageView image_view = nullptr;
// Image layout
VkImageLayout image_layout = VK_IMAGE_LAYOUT_UNDEFINED;
// Memory buffer
VkDeviceMemory memory = nullptr;
// Image sample count
VkSampleCountFlagBits sample_count = VK_SAMPLE_COUNT_1_BIT;
// (if a depth view) Image view of depth aspect
VkImageView image_view_depth = nullptr;
// (if a depth view) Image view of stencil aspect
VkImageView image_view_stencil = nullptr;
CachedTileView(ui::vulkan::VulkanDevice* device, VkDeviceMemory edram_memory,
TileViewKey view_key);
~CachedTileView();
VkResult Initialize(VkCommandBuffer command_buffer);
bool IsEqual(const TileViewKey& other_key) const {
auto a = reinterpret_cast<const uint64_t*>(&key);
auto b = reinterpret_cast<const uint64_t*>(&other_key);
return *a == *b;
}
bool operator<(const CachedTileView& other) const {
return key.tile_offset < other.key.tile_offset;
}
VkExtent2D GetSize() const {
return {key.tile_width * 80u, key.tile_height * 16u};
}
private:
ui::vulkan::VulkanDevice* device_ = nullptr;
};
// Parsed render configuration from the current render state.
struct RenderConfiguration {
// Render mode (color+depth, depth-only, etc).
xenos::ModeControl mode_control;
// Target surface pitch multiplied by MSAA, in pixels.
uint32_t surface_pitch_px;
// ESTIMATED target surface height multiplied by MSAA, in pixels.
uint32_t surface_height_px;
// Surface MSAA setting.
xenos::MsaaSamples surface_msaa;
// Color attachments for the 4 render targets.
struct {
bool used;
uint32_t edram_base;
xenos::ColorRenderTargetFormat format;
} color[4];
// Depth/stencil attachment.
struct {
bool used;
uint32_t edram_base;
xenos::DepthRenderTargetFormat format;
} depth_stencil;
};
// Current render state based on the register-specified configuration.
struct RenderState {
// Parsed configuration.
RenderConfiguration config;
// Render pass (to be used with pipelines/etc).
CachedRenderPass* render_pass = nullptr;
VkRenderPass render_pass_handle = nullptr;
// Target framebuffer bound to the render pass.
CachedFramebuffer* framebuffer = nullptr;
VkFramebuffer framebuffer_handle = nullptr;
bool color_attachment_written[4] = {false};
bool depth_attachment_written = false;
};
// Manages the virtualized EDRAM and the render target cache.
//
// On the 360 the render target is an opaque block of memory in EDRAM that's
// only accessible via resolves. We use this to our advantage to simulate
// something like it as best we can by having a shared backing memory with
// a multitude of views for each tile location in EDRAM.
//
// This allows us to have the same base address write to the same memory
// regardless of framebuffer format. Resolving then uses whatever format the
// resolve requests straight from the backing memory.
//
// EDRAM is a beast and we only approximate it as best we can. Basically,
// the 10MiB of EDRAM is composed of 2048 5120b tiles. Each tile is 80x16px.
// +-----+-----+-----+---
// |tile0|tile1|tile2|... 2048 times
// +-----+-----+-----+---
// Operations dealing with EDRAM deal in tile offsets, so base 0x100 is tile
// offset 256, 256*5120=1310720b into the buffer. All rendering operations are
// aligned to tiles so trying to draw at 256px wide will have a real width of
// 320px by rounding up to the next tile.
//
// MSAA and other settings will modify the exact pixel sizes, like 4X makes
// each tile effectively 40x8px / 2X makes each tile 80x8px, but they are still
// all 5120b. As we try to emulate this we adjust our viewport when rendering to
// stretch pixels as needed.
//
// It appears that games also take advantage of MSAA stretching tiles when doing
// clears. Games will clear a view with 1/2X pitch/height and 4X MSAA and then
// later draw to that view with 1X pitch/height and 1X MSAA.
//
// The good news is that games cannot read EDRAM directly but must use a copy
// operation to get the data out. That gives us a chance to do whatever we
// need to (re-tile, etc) only when requested.
//
// To approximate the tiled EDRAM layout we use a single large chunk of memory.
// From this memory we create many VkImages (and VkImageViews) of various
// formats and dimensions as requested by the game. These are used as
// attachments during rendering and as sources during copies. They are also
// heavily aliased - lots of images will reference the same locations in the
// underlying EDRAM buffer. The only requirement is that there are no hazards
// with specific tiles (reading/writing the same tile through different images)
// and otherwise it should be ok *fingers crossed*.
//
// One complication is the copy/resolve process itself: we need to give back
// the data asked for in the format desired and where it goes is arbitrary
// (any address in physical memory). If the game is good we get resolves of
// EDRAM into fixed base addresses with scissored regions. If the game is bad
// we are broken.
//
// Resolves from EDRAM result in tiled textures - that's texture tiles, not
// EDRAM tiles. If we wanted to ensure byte-for-byte correctness we'd need to
// then tile the images as we wrote them out. For now, we just attempt to
// get the (X, Y) in linear space and do that. This really comes into play
// when multiple resolves write to the same texture or memory aliased by
// multiple textures - which is common due to predicated tiling. The examples
// below demonstrate what this looks like, but the important thing is that
// we are aware of partial textures and overlapping regions.
//
// TODO(benvanik): what, if any, barriers do we need? any transitions?
//
// Example with multiple render targets:
// Two color targets of 256x256px tightly packed in EDRAM:
// color target 0: base 0x0, pitch 320, scissor 0,0, 256x256
// starts at tile 0, buffer offset 0
// contains 64 tiles (320/80)*(256/16)
// color target 1: base 0x40, pitch 320, scissor 256,0, 256x256
// starts at tile 64 (after color target 0), buffer offset 327680b
// contains 64 tiles
// In EDRAM each set of 64 tiles is contiguous:
// +------+------+ +------+------+------+
// |ct0.0 |ct0.1 |...|ct0.63|ct1.0 |ct1.1 |...
// +------+------+ +------+------+------+
// To render into these, we setup two VkImages:
// image 0: bound to buffer offset 0, 320x256x4=327680b
// image 1: bound to buffer offset 327680b, 320x256x4=327680b
// So when we render to them:
// +------+-+ scissored to 256x256, actually 320x256
// | . | | <- . appears at some untiled offset in the buffer, but
// | | | consistent if aliased with the same format
// +------+-+
// In theory, this gives us proper aliasing in most cases.
//
// Example with horizontal predicated tiling:
// Trying to render 1024x576 @4X MSAA, splitting into two regions
// horizontally:
// +----------+
// | 1024x288 |
// +----------+
// | 1024x288 |
// +----------+
// EDRAM configured for 1056x288px with tile size 2112x567px (4X MSAA):
// color target 0: base 0x0, pitch 1080, 26x36 tiles
// First render (top):
// window offset 0,0
// scissor 0,0, 1024x288
// First resolve (top):
// RB_COPY_DEST_BASE 0x1F45D000
// RB_COPY_DEST_PITCH pitch=1024, height=576
// vertices: 0,0, 1024,0, 1024,288
// Second render (bottom):
// window offset 0,-288
// scissor 0,288, 1024x288
// Second resolve (bottom):
// RB_COPY_DEST_BASE 0x1F57D000 (+1179648b)
// RB_COPY_DEST_PITCH pitch=1024, height=576
// (exactly 1024x288*4b after first resolve)
// vertices: 0,288, 1024,288, 1024,576
// Resolving here is easy as the textures are contiguous in memory. We can
// snoop in the first resolve with the dest height to know the total size,
// and in the second resolve see that it overlaps and place it in the
// existing target.
//
// Example with vertical predicated tiling:
// Trying to render 1280x720 @2X MSAA, splitting into two regions
// vertically:
// +-----+-----+
// | 640 | 640 |
// | x | x |
// | 720 | 720 |
// +-----+-----+
// EDRAM configured for 640x736px with tile size 640x1472px (2X MSAA):
// color target 0: base 0x0, pitch 640, 8x92 tiles
// First render (left):
// window offset 0,0
// scissor 0,0, 640x720
// First resolve (left):
// RB_COPY_DEST_BASE 0x1BC6D000
// RB_COPY_DEST_PITCH pitch=1280, height=720
// vertices: 0,0, 640,0, 640,720
// Second render (right):
// window offset -640,0
// scissor 640,0, 640x720
// Second resolve (right):
// RB_COPY_DEST_BASE 0x1BC81000 (+81920b)
// RB_COPY_DEST_PITCH pitch=1280, height=720
// vertices: 640,0, 1280,0, 1280,720
// Resolving here is much more difficult as resolves are tiled and the right
// half of the texture is 81920b away:
// 81920/4bpp=20480px, /32 (texture tile size)=640px
// We know the texture size with the first resolve and with the second we
// must check for overlap then compute the offset (in both X and Y).
class RenderCache {
public:
RenderCache(RegisterFile* register_file, ui::vulkan::VulkanDevice* device);
~RenderCache();
VkResult Initialize();
void Shutdown();
// Call this to determine if you should start a new render pass or continue
// with an already open pass.
bool dirty() const;
CachedTileView* FindTileView(uint32_t base, uint32_t pitch,
xenos::MsaaSamples samples, bool color_or_depth,
uint32_t format);
// Begins a render pass targeting the state-specified framebuffer formats.
// The command buffer will be transitioned into the render pass phase.
const RenderState* BeginRenderPass(VkCommandBuffer command_buffer,
VulkanShader* vertex_shader,
VulkanShader* pixel_shader);
// Ends the current render pass.
// The command buffer will be transitioned out of the render pass phase.
void EndRenderPass();
// Clears all cached content.
void ClearCache();
// Queues commands to copy EDRAM contents into an image.
// The command buffer must not be inside of a render pass when calling this.
void RawCopyToImage(VkCommandBuffer command_buffer, uint32_t edram_base,
VkImage image, VkImageLayout image_layout,
bool color_or_depth, VkOffset3D offset,
VkExtent3D extents);
// Queues commands to blit EDRAM contents into an image.
// The command buffer must not be inside of a render pass when calling this.
void BlitToImage(VkCommandBuffer command_buffer, uint32_t edram_base,
uint32_t pitch, uint32_t height,
xenos::MsaaSamples num_samples, VkImage image,
VkImageLayout image_layout, bool color_or_depth,
uint32_t format, VkFilter filter, VkOffset3D offset,
VkExtent3D extents);
// Queues commands to clear EDRAM contents with a solid color.
// The command buffer must not be inside of a render pass when calling this.
void ClearEDRAMColor(VkCommandBuffer command_buffer, uint32_t edram_base,
xenos::ColorRenderTargetFormat format, uint32_t pitch,
uint32_t height, xenos::MsaaSamples num_samples,
float* color);
// Queues commands to clear EDRAM contents with depth/stencil values.
// The command buffer must not be inside of a render pass when calling this.
void ClearEDRAMDepthStencil(VkCommandBuffer command_buffer,
uint32_t edram_base,
xenos::DepthRenderTargetFormat format,
uint32_t pitch, uint32_t height,
xenos::MsaaSamples num_samples, float depth,
uint32_t stencil);
// Queues commands to fill EDRAM contents with a constant value.
// The command buffer must not be inside of a render pass when calling this.
void FillEDRAM(VkCommandBuffer command_buffer, uint32_t value);
private:
// Parses the current state into a configuration object.
bool ParseConfiguration(RenderConfiguration* config);
// Finds a tile view. Returns nullptr if none found matching the key.
CachedTileView* FindTileView(const TileViewKey& view_key) const;
// Gets or creates a tile view with the given parameters.
CachedTileView* FindOrCreateTileView(VkCommandBuffer command_buffer,
const TileViewKey& view_key);
void UpdateTileView(VkCommandBuffer command_buffer, CachedTileView* view,
bool load, bool insert_barrier = true);
// Gets or creates a render pass and frame buffer for the given configuration.
// This attempts to reuse as much as possible across render passes and
// framebuffers.
bool ConfigureRenderPass(VkCommandBuffer command_buffer,
RenderConfiguration* config,
CachedRenderPass** out_render_pass,
CachedFramebuffer** out_framebuffer);
RegisterFile* register_file_ = nullptr;
ui::vulkan::VulkanDevice* device_ = nullptr;
// Entire 10MiB of EDRAM.
VkDeviceMemory edram_memory_ = nullptr;
// Buffer overlayed 1:1 with edram_memory_ to allow raw access.
VkBuffer edram_buffer_ = nullptr;
// Cache of VkImage and VkImageView's for all of our EDRAM tilings.
// TODO(benvanik): non-linear lookup? Should only be a small number of these.
std::vector<CachedTileView*> cached_tile_views_;
// Cache of render passes based on formats.
std::vector<CachedRenderPass*> cached_render_passes_;
// Shadows of the registers that impact the render pass we choose.
// If the registers don't change between passes we can quickly reuse the
// previous one.
struct ShadowRegisters {
reg::RB_MODECONTROL rb_modecontrol;
reg::RB_SURFACE_INFO rb_surface_info;
reg::RB_COLOR_INFO rb_color_info;
reg::RB_COLOR_INFO rb_color1_info;
reg::RB_COLOR_INFO rb_color2_info;
reg::RB_COLOR_INFO rb_color3_info;
reg::RB_DEPTH_INFO rb_depth_info;
uint32_t pa_sc_window_scissor_tl;
uint32_t pa_sc_window_scissor_br;
ShadowRegisters() { Reset(); }
void Reset() { std::memset(this, 0, sizeof(*this)); }
} shadow_registers_;
bool SetShadowRegister(uint32_t* dest, uint32_t register_name);
// Configuration used for the current/previous Begin/End, representing the
// current shadow register state.
RenderState current_state_;
// Only valid during a BeginRenderPass/EndRenderPass block.
VkCommandBuffer current_command_buffer_ = nullptr;
};
} // namespace vulkan
} // namespace gpu
} // namespace xe
#endif // XENIA_GPU_VULKAN_RENDER_CACHE_H_

View File

@@ -1,50 +0,0 @@
// generated from `xb genspirv`
// source: dummy.frag
const uint8_t dummy_frag[] = {
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x08, 0x00,
0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x2B, 0x00, 0x00, 0x00,
0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00,
0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,
0x31, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00,
0xC2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00, 0x47, 0x4C, 0x5F, 0x41,
0x52, 0x42, 0x5F, 0x65, 0x78, 0x70, 0x6C, 0x69, 0x63, 0x69, 0x74, 0x5F,
0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x5F, 0x6C, 0x6F, 0x63, 0x61, 0x74,
0x69, 0x6F, 0x6E, 0x00, 0x04, 0x00, 0x09, 0x00, 0x47, 0x4C, 0x5F, 0x41,
0x52, 0x42, 0x5F, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5F,
0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5F, 0x6F, 0x62, 0x6A, 0x65, 0x63,
0x74, 0x73, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00, 0x47, 0x4C, 0x5F, 0x41,
0x52, 0x42, 0x5F, 0x73, 0x68, 0x61, 0x64, 0x69, 0x6E, 0x67, 0x5F, 0x6C,
0x61, 0x6E, 0x67, 0x75, 0x61, 0x67, 0x65, 0x5F, 0x34, 0x32, 0x30, 0x70,
0x61, 0x63, 0x6B, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,
0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x07, 0x00,
0x2D, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x5F, 0x69, 0x6E, 0x74, 0x65, 0x72,
0x70, 0x6F, 0x6C, 0x61, 0x74, 0x6F, 0x72, 0x73, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x03, 0x00, 0x31, 0x00, 0x00, 0x00, 0x6F, 0x43, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x31, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00,
0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00,
0x09, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x2B, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x2C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00,
0x2E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00,
0x2F, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x2F, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x30, 0x00, 0x00, 0x00,
0x31, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00,
0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00,
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
};

View File

@@ -1,37 +0,0 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 6
; Bound: 50
; Schema: 0
OpCapability Shader
OpCapability Sampled1D
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %in_interpolators %oC
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpSourceExtension "GL_ARB_explicit_attrib_location"
OpSourceExtension "GL_ARB_separate_shader_objects"
OpSourceExtension "GL_ARB_shading_language_420pack"
OpName %main "main"
OpName %in_interpolators "in_interpolators"
OpName %oC "oC"
OpDecorate %in_interpolators Location 0
OpDecorate %oC Location 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%uint = OpTypeInt 32 0
%uint_16 = OpConstant %uint 16
%_arr_v4float_uint_16 = OpTypeArray %v4float %uint_16
%_ptr_Input__arr_v4float_uint_16 = OpTypePointer Input %_arr_v4float_uint_16
%in_interpolators = OpVariable %_ptr_Input__arr_v4float_uint_16 Input
%uint_4 = OpConstant %uint 4
%_arr_v4float_uint_4 = OpTypeArray %v4float %uint_4
%_ptr_Output__arr_v4float_uint_4 = OpTypePointer Output %_arr_v4float_uint_4
%oC = OpVariable %_ptr_Output__arr_v4float_uint_4 Output
%main = OpFunction %void None %3
%5 = OpLabel
OpReturn
OpFunctionEnd

View File

@@ -1,183 +0,0 @@
// generated from `xb genspirv`
// source: line_quad_list.geom
const uint8_t line_quad_list_geom[] = {
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x08, 0x00,
0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x18, 0x00, 0x00, 0x00,
0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00,
0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x0C, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
0x12, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
0x4D, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x10, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,
0x02, 0x00, 0x00, 0x00, 0xC2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00,
0x47, 0x4C, 0x5F, 0x41, 0x52, 0x42, 0x5F, 0x65, 0x78, 0x70, 0x6C, 0x69,
0x63, 0x69, 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x5F, 0x6C,
0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x04, 0x00, 0x09, 0x00,
0x47, 0x4C, 0x5F, 0x41, 0x52, 0x42, 0x5F, 0x73, 0x65, 0x70, 0x61, 0x72,
0x61, 0x74, 0x65, 0x5F, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5F, 0x6F,
0x62, 0x6A, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50,
0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x00,
0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x53, 0x69, 0x7A, 0x65,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x0A, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x0D, 0x00, 0x00, 0x00,
0x67, 0x6C, 0x5F, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78,
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x0D, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x73, 0x69, 0x74,
0x69, 0x6F, 0x6E, 0x00, 0x06, 0x00, 0x07, 0x00, 0x0D, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x69, 0x6E, 0x74,
0x53, 0x69, 0x7A, 0x65, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
0x12, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x69, 0x6E, 0x00, 0x00, 0x00,
0x05, 0x00, 0x07, 0x00, 0x21, 0x00, 0x00, 0x00, 0x6F, 0x75, 0x74, 0x5F,
0x69, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x6F, 0x6C, 0x61, 0x74, 0x6F, 0x72,
0x73, 0x00, 0x00, 0x00, 0x05, 0x00, 0x07, 0x00, 0x24, 0x00, 0x00, 0x00,
0x69, 0x6E, 0x5F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x6F, 0x6C, 0x61,
0x74, 0x6F, 0x72, 0x73, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00,
0x4D, 0x00, 0x00, 0x00, 0x5F, 0x69, 0x6E, 0x5F, 0x70, 0x6F, 0x69, 0x6E,
0x74, 0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x5F, 0x75, 0x6E, 0x75, 0x73,
0x65, 0x64, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0x50, 0x00, 0x00, 0x00,
0x5F, 0x69, 0x6E, 0x5F, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x5F, 0x73, 0x69,
0x7A, 0x65, 0x5F, 0x75, 0x6E, 0x75, 0x73, 0x65, 0x64, 0x00, 0x00, 0x00,
0x05, 0x00, 0x08, 0x00, 0x52, 0x00, 0x00, 0x00, 0x5F, 0x6F, 0x75, 0x74,
0x5F, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64,
0x5F, 0x75, 0x6E, 0x75, 0x73, 0x65, 0x64, 0x00, 0x48, 0x00, 0x05, 0x00,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x47, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x48, 0x00, 0x05, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
0x0D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x0D, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
0x24, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x50, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
0x52, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00,
0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00,
0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
0x09, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x15, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x04, 0x00,
0x0D, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x15, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00,
0x10, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00,
0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x19, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00,
0x1F, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x1F, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00,
0x21, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00,
0x22, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x22, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x39, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
0x4A, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x04, 0x00, 0x4B, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x4C, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
0x4C, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x04, 0x00, 0x4E, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x4F, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
0x4F, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x51, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x4A, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x51, 0x00, 0x00, 0x00,
0x52, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00,
0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00,
0x41, 0x00, 0x06, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x12, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x16, 0x00, 0x00, 0x00,
0x17, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x41, 0x00, 0x06, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00,
0x12, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1C, 0x00, 0x00, 0x00,
0x1D, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x1F, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x21, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
0xDA, 0x00, 0x01, 0x00, 0x41, 0x00, 0x06, 0x00, 0x13, 0x00, 0x00, 0x00,
0x28, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
0x29, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0x17, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
0x19, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x1F, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x21, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00,
0xDA, 0x00, 0x01, 0x00, 0x41, 0x00, 0x06, 0x00, 0x13, 0x00, 0x00, 0x00,
0x31, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
0x32, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0x17, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
0x19, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
0x30, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x1F, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x21, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
0xDA, 0x00, 0x01, 0x00, 0x41, 0x00, 0x06, 0x00, 0x13, 0x00, 0x00, 0x00,
0x3A, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0x17, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
0x19, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
0x39, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x1F, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x21, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00,
0xDA, 0x00, 0x01, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x1D, 0x00, 0x00, 0x00,
0x1B, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x21, 0x00, 0x00, 0x00,
0x27, 0x00, 0x00, 0x00, 0xDA, 0x00, 0x01, 0x00, 0xDB, 0x00, 0x01, 0x00,
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
};

View File

@@ -1,132 +0,0 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 6
; Bound: 83
; Schema: 0
OpCapability Geometry
OpCapability GeometryPointSize
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Geometry %main "main" %_ %gl_in %out_interpolators %in_interpolators %_in_point_coord_unused %_in_point_size_unused %_out_point_coord_unused
OpExecutionMode %main InputLinesAdjacency
OpExecutionMode %main Invocations 1
OpExecutionMode %main OutputLineStrip
OpExecutionMode %main OutputVertices 5
OpSource GLSL 450
OpSourceExtension "GL_ARB_explicit_attrib_location"
OpSourceExtension "GL_ARB_separate_shader_objects"
OpName %main "main"
OpName %gl_PerVertex "gl_PerVertex"
OpMemberName %gl_PerVertex 0 "gl_Position"
OpMemberName %gl_PerVertex 1 "gl_PointSize"
OpName %_ ""
OpName %gl_PerVertex_0 "gl_PerVertex"
OpMemberName %gl_PerVertex_0 0 "gl_Position"
OpMemberName %gl_PerVertex_0 1 "gl_PointSize"
OpName %gl_in "gl_in"
OpName %out_interpolators "out_interpolators"
OpName %in_interpolators "in_interpolators"
OpName %_in_point_coord_unused "_in_point_coord_unused"
OpName %_in_point_size_unused "_in_point_size_unused"
OpName %_out_point_coord_unused "_out_point_coord_unused"
OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
OpDecorate %gl_PerVertex Block
OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
OpDecorate %gl_PerVertex_0 Block
OpDecorate %out_interpolators Location 0
OpDecorate %in_interpolators Location 0
OpDecorate %_in_point_coord_unused Location 16
OpDecorate %_in_point_size_unused Location 17
OpDecorate %_out_point_coord_unused Location 16
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%gl_PerVertex = OpTypeStruct %v4float %float
%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
%_ = OpVariable %_ptr_Output_gl_PerVertex Output
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%gl_PerVertex_0 = OpTypeStruct %v4float %float
%uint = OpTypeInt 32 0
%uint_4 = OpConstant %uint 4
%_arr_gl_PerVertex_0_uint_4 = OpTypeArray %gl_PerVertex_0 %uint_4
%_ptr_Input__arr_gl_PerVertex_0_uint_4 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_4
%gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_4 Input
%_ptr_Input_v4float = OpTypePointer Input %v4float
%_ptr_Output_v4float = OpTypePointer Output %v4float
%int_1 = OpConstant %int 1
%_ptr_Input_float = OpTypePointer Input %float
%_ptr_Output_float = OpTypePointer Output %float
%uint_16 = OpConstant %uint 16
%_arr_v4float_uint_16 = OpTypeArray %v4float %uint_16
%_ptr_Output__arr_v4float_uint_16 = OpTypePointer Output %_arr_v4float_uint_16
%out_interpolators = OpVariable %_ptr_Output__arr_v4float_uint_16 Output
%_arr__arr_v4float_uint_16_uint_4 = OpTypeArray %_arr_v4float_uint_16 %uint_4
%_ptr_Input__arr__arr_v4float_uint_16_uint_4 = OpTypePointer Input %_arr__arr_v4float_uint_16_uint_4
%in_interpolators = OpVariable %_ptr_Input__arr__arr_v4float_uint_16_uint_4 Input
%_ptr_Input__arr_v4float_uint_16 = OpTypePointer Input %_arr_v4float_uint_16
%int_2 = OpConstant %int 2
%int_3 = OpConstant %int 3
%v2float = OpTypeVector %float 2
%_arr_v2float_uint_4 = OpTypeArray %v2float %uint_4
%_ptr_Input__arr_v2float_uint_4 = OpTypePointer Input %_arr_v2float_uint_4
%_in_point_coord_unused = OpVariable %_ptr_Input__arr_v2float_uint_4 Input
%_arr_float_uint_4 = OpTypeArray %float %uint_4
%_ptr_Input__arr_float_uint_4 = OpTypePointer Input %_arr_float_uint_4
%_in_point_size_unused = OpVariable %_ptr_Input__arr_float_uint_4 Input
%_ptr_Output_v2float = OpTypePointer Output %v2float
%_out_point_coord_unused = OpVariable %_ptr_Output_v2float Output
%main = OpFunction %void None %3
%5 = OpLabel
%20 = OpAccessChain %_ptr_Input_v4float %gl_in %int_0 %int_0
%21 = OpLoad %v4float %20
%23 = OpAccessChain %_ptr_Output_v4float %_ %int_0
OpStore %23 %21
%26 = OpAccessChain %_ptr_Input_float %gl_in %int_0 %int_1
%27 = OpLoad %float %26
%29 = OpAccessChain %_ptr_Output_float %_ %int_1
OpStore %29 %27
%38 = OpAccessChain %_ptr_Input__arr_v4float_uint_16 %in_interpolators %int_0
%39 = OpLoad %_arr_v4float_uint_16 %38
OpStore %out_interpolators %39
OpEmitVertex
%40 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0
%41 = OpLoad %v4float %40
OpStore %23 %41
%43 = OpAccessChain %_ptr_Input_float %gl_in %int_1 %int_1
%44 = OpLoad %float %43
OpStore %29 %44
%46 = OpAccessChain %_ptr_Input__arr_v4float_uint_16 %in_interpolators %int_1
%47 = OpLoad %_arr_v4float_uint_16 %46
OpStore %out_interpolators %47
OpEmitVertex
%49 = OpAccessChain %_ptr_Input_v4float %gl_in %int_2 %int_0
%50 = OpLoad %v4float %49
OpStore %23 %50
%52 = OpAccessChain %_ptr_Input_float %gl_in %int_2 %int_1
%53 = OpLoad %float %52
OpStore %29 %53
%55 = OpAccessChain %_ptr_Input__arr_v4float_uint_16 %in_interpolators %int_2
%56 = OpLoad %_arr_v4float_uint_16 %55
OpStore %out_interpolators %56
OpEmitVertex
%58 = OpAccessChain %_ptr_Input_v4float %gl_in %int_3 %int_0
%59 = OpLoad %v4float %58
OpStore %23 %59
%61 = OpAccessChain %_ptr_Input_float %gl_in %int_3 %int_1
%62 = OpLoad %float %61
OpStore %29 %62
%64 = OpAccessChain %_ptr_Input__arr_v4float_uint_16 %in_interpolators %int_3
%65 = OpLoad %_arr_v4float_uint_16 %64
OpStore %out_interpolators %65
OpEmitVertex
OpStore %23 %21
OpStore %29 %27
OpStore %out_interpolators %39
OpEmitVertex
OpEndPrimitive
OpReturn
OpFunctionEnd

View File

@@ -1,245 +0,0 @@
// generated from `xb genspirv`
// source: point_list.geom
const uint8_t point_list_geom[] = {
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x08, 0x00,
0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x02, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
0x47, 0x4C, 0x53, 0x4C, 0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30,
0x00, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0C, 0x00, 0x03, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00,
0x5F, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00,
0x73, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00,
0x13, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00,
0x04, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x00,
0x04, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xC2, 0x01, 0x00, 0x00,
0x04, 0x00, 0x09, 0x00, 0x47, 0x4C, 0x5F, 0x41, 0x52, 0x42, 0x5F, 0x65,
0x78, 0x70, 0x6C, 0x69, 0x63, 0x69, 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72,
0x69, 0x62, 0x5F, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00,
0x04, 0x00, 0x09, 0x00, 0x47, 0x4C, 0x5F, 0x41, 0x52, 0x42, 0x5F, 0x73,
0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x5F, 0x73, 0x68, 0x61, 0x64,
0x65, 0x72, 0x5F, 0x6F, 0x62, 0x6A, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00,
0x04, 0x00, 0x09, 0x00, 0x47, 0x4C, 0x5F, 0x41, 0x52, 0x42, 0x5F, 0x73,
0x68, 0x61, 0x64, 0x69, 0x6E, 0x67, 0x5F, 0x6C, 0x61, 0x6E, 0x67, 0x75,
0x61, 0x67, 0x65, 0x5F, 0x34, 0x32, 0x30, 0x70, 0x61, 0x63, 0x6B, 0x00,
0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x0A, 0x00, 0x00, 0x00,
0x67, 0x6C, 0x5F, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78,
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x0A, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x73, 0x69, 0x74,
0x69, 0x6F, 0x6E, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x67, 0x6C, 0x5F, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x05, 0x00, 0x07, 0x00,
0x18, 0x00, 0x00, 0x00, 0x70, 0x75, 0x73, 0x68, 0x5F, 0x63, 0x6F, 0x6E,
0x73, 0x74, 0x73, 0x5F, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x07, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x77, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x5F, 0x73, 0x63, 0x61, 0x6C, 0x65,
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x18, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x76, 0x74, 0x78, 0x5F, 0x66, 0x6D, 0x74, 0x00,
0x06, 0x00, 0x06, 0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x70, 0x6F, 0x69, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, 0x65, 0x00, 0x00,
0x06, 0x00, 0x06, 0x00, 0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x61, 0x6C, 0x70, 0x68, 0x61, 0x5F, 0x74, 0x65, 0x73, 0x74, 0x00, 0x00,
0x06, 0x00, 0x07, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x70, 0x73, 0x5F, 0x70, 0x61, 0x72, 0x61, 0x6D, 0x5F, 0x67, 0x65, 0x6E,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x1A, 0x00, 0x00, 0x00,
0x70, 0x75, 0x73, 0x68, 0x5F, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E,
0x74, 0x73, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x22, 0x00, 0x00, 0x00,
0x70, 0x6F, 0x69, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, 0x65, 0x00, 0x00,
0x05, 0x00, 0x06, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50,
0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x06, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x00,
0x05, 0x00, 0x03, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x05, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x64, 0x65,
0x78, 0x61, 0x62, 0x6C, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x07, 0x00,
0x5F, 0x00, 0x00, 0x00, 0x6F, 0x75, 0x74, 0x5F, 0x69, 0x6E, 0x74, 0x65,
0x72, 0x70, 0x6F, 0x6C, 0x61, 0x74, 0x6F, 0x72, 0x73, 0x00, 0x00, 0x00,
0x05, 0x00, 0x07, 0x00, 0x62, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x5F, 0x69,
0x6E, 0x74, 0x65, 0x72, 0x70, 0x6F, 0x6C, 0x61, 0x74, 0x6F, 0x72, 0x73,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x67, 0x00, 0x00, 0x00,
0x70, 0x6F, 0x69, 0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x00,
0x05, 0x00, 0x05, 0x00, 0x69, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x64, 0x65,
0x78, 0x61, 0x62, 0x6C, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00,
0x73, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x5F, 0x70, 0x6F, 0x69, 0x6E, 0x74,
0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x5F, 0x75, 0x6E, 0x75, 0x73, 0x65,
0x64, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x47, 0x00, 0x03, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x48, 0x00, 0x05, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x18, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x48, 0x00, 0x05, 0x00, 0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x23, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x18, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x5F, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
0x62, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0x67, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x73, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00,
0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x03, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x0D, 0x00, 0x00, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x0E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x07, 0x00, 0x18, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
0x19, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00,
0x20, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00,
0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, 0x27, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x03, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x3E, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
0x3E, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x43, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xBF,
0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0x3F, 0x2C, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00,
0x46, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00,
0x2C, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00,
0x45, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x05, 0x00,
0x15, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
0x44, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00,
0x49, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
0x2C, 0x00, 0x07, 0x00, 0x43, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00,
0x46, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
0x49, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x4C, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x5A, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x5D, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x5E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x5E, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x60, 0x00, 0x00, 0x00,
0x5D, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x61, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x61, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x63, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x66, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x66, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00,
0x6C, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x6F, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x71, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x72, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
0x4C, 0x00, 0x00, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x12, 0x00, 0x00, 0x00,
0x13, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
0x11, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00,
0x1B, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x4F, 0x00, 0x07, 0x00,
0x15, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x23, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
0x22, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
0xBA, 0x00, 0x05, 0x00, 0x27, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00,
0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00,
0x28, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x02, 0x00, 0x29, 0x00, 0x00, 0x00, 0x50, 0x00, 0x05, 0x00,
0x15, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
0x25, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0x2A, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x02, 0x00, 0x2A, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x07, 0x00,
0x15, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x07, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00,
0x4F, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
0x2F, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00,
0x32, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
0xF9, 0x00, 0x02, 0x00, 0x35, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
0x35, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x07, 0x00, 0x10, 0x00, 0x00, 0x00,
0x75, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0x70, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0xB1, 0x00, 0x05, 0x00,
0x27, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x00, 0x00, 0xF6, 0x00, 0x04, 0x00, 0x37, 0x00, 0x00, 0x00,
0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00,
0x3C, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x02, 0x00, 0x36, 0x00, 0x00, 0x00, 0x4F, 0x00, 0x07, 0x00,
0x15, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x4D, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x16, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x00, 0x00,
0x4D, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x15, 0x00, 0x00, 0x00, 0x4F, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x00, 0x00,
0x85, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00,
0x4F, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
0x15, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00,
0x51, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
0x55, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00,
0x06, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
0x58, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00,
0x55, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00,
0x58, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x5A, 0x00, 0x00, 0x00,
0x5B, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x5B, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x63, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
0x62, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x5D, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x69, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x16, 0x00, 0x00, 0x00, 0x6A, 0x00, 0x00, 0x00,
0x69, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x15, 0x00, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x00, 0x6A, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x00, 0x6D, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x00,
0x6C, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x67, 0x00, 0x00, 0x00,
0x6D, 0x00, 0x00, 0x00, 0xDA, 0x00, 0x01, 0x00, 0x80, 0x00, 0x05, 0x00,
0x10, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00,
0x6F, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0x35, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x02, 0x00, 0x37, 0x00, 0x00, 0x00, 0xDB, 0x00, 0x01, 0x00,
0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
};

View File

@@ -1,167 +0,0 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 6
; Bound: 118
; Schema: 0
OpCapability Geometry
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Geometry %main "main" %gl_in %point_size %_ %out_interpolators %in_interpolators %point_coord %in_point_coord_unused
OpExecutionMode %main InputPoints
OpExecutionMode %main Invocations 1
OpExecutionMode %main OutputTriangleStrip
OpExecutionMode %main OutputVertices 4
OpSource GLSL 450
OpSourceExtension "GL_ARB_explicit_attrib_location"
OpSourceExtension "GL_ARB_separate_shader_objects"
OpSourceExtension "GL_ARB_shading_language_420pack"
OpName %main "main"
OpName %gl_PerVertex "gl_PerVertex"
OpMemberName %gl_PerVertex 0 "gl_Position"
OpName %gl_in "gl_in"
OpName %push_consts_type "push_consts_type"
OpMemberName %push_consts_type 0 "window_scale"
OpMemberName %push_consts_type 1 "vtx_fmt"
OpMemberName %push_consts_type 2 "point_size"
OpMemberName %push_consts_type 3 "alpha_test"
OpMemberName %push_consts_type 4 "ps_param_gen"
OpName %push_constants "push_constants"
OpName %point_size "point_size"
OpName %gl_PerVertex_0 "gl_PerVertex"
OpMemberName %gl_PerVertex_0 0 "gl_Position"
OpName %_ ""
OpName %indexable "indexable"
OpName %out_interpolators "out_interpolators"
OpName %in_interpolators "in_interpolators"
OpName %point_coord "point_coord"
OpName %indexable_0 "indexable"
OpName %in_point_coord_unused "in_point_coord_unused"
OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
OpDecorate %gl_PerVertex Block
OpMemberDecorate %push_consts_type 0 Offset 0
OpMemberDecorate %push_consts_type 1 Offset 16
OpMemberDecorate %push_consts_type 2 Offset 32
OpMemberDecorate %push_consts_type 3 Offset 48
OpMemberDecorate %push_consts_type 4 Offset 64
OpDecorate %push_consts_type Block
OpDecorate %point_size Location 17
OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
OpDecorate %gl_PerVertex_0 Block
OpDecorate %out_interpolators Location 0
OpDecorate %in_interpolators Location 0
OpDecorate %point_coord Location 16
OpDecorate %in_point_coord_unused Location 16
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%gl_PerVertex = OpTypeStruct %v4float
%uint = OpTypeInt 32 0
%uint_1 = OpConstant %uint 1
%_arr_gl_PerVertex_uint_1 = OpTypeArray %gl_PerVertex %uint_1
%_ptr_Input__arr_gl_PerVertex_uint_1 = OpTypePointer Input %_arr_gl_PerVertex_uint_1
%gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_uint_1 Input
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%_ptr_Input_v4float = OpTypePointer Input %v4float
%v2float = OpTypeVector %float 2
%_ptr_Function_v2float = OpTypePointer Function %v2float
%push_consts_type = OpTypeStruct %v4float %v4float %v4float %v4float %uint
%_ptr_PushConstant_push_consts_type = OpTypePointer PushConstant %push_consts_type
%push_constants = OpVariable %_ptr_PushConstant_push_consts_type PushConstant
%int_2 = OpConstant %int 2
%_ptr_PushConstant_v4float = OpTypePointer PushConstant %v4float
%_arr_float_uint_1 = OpTypeArray %float %uint_1
%_ptr_Input__arr_float_uint_1 = OpTypePointer Input %_arr_float_uint_1
%point_size = OpVariable %_ptr_Input__arr_float_uint_1 Input
%_ptr_Input_float = OpTypePointer Input %float
%float_0 = OpConstant %float 0
%bool = OpTypeBool
%int_4 = OpConstant %int 4
%gl_PerVertex_0 = OpTypeStruct %v4float
%_ptr_Output_gl_PerVertex_0 = OpTypePointer Output %gl_PerVertex_0
%_ = OpVariable %_ptr_Output_gl_PerVertex_0 Output
%uint_4 = OpConstant %uint 4
%_arr_v2float_uint_4 = OpTypeArray %v2float %uint_4
%float_n1 = OpConstant %float -1
%float_1 = OpConstant %float 1
%70 = OpConstantComposite %v2float %float_n1 %float_1
%71 = OpConstantComposite %v2float %float_1 %float_1
%72 = OpConstantComposite %v2float %float_n1 %float_n1
%73 = OpConstantComposite %v2float %float_1 %float_n1
%74 = OpConstantComposite %_arr_v2float_uint_4 %70 %71 %72 %73
%_ptr_Function__arr_v2float_uint_4 = OpTypePointer Function %_arr_v2float_uint_4
%_ptr_Output_v4float = OpTypePointer Output %v4float
%uint_16 = OpConstant %uint 16
%_arr_v4float_uint_16 = OpTypeArray %v4float %uint_16
%_ptr_Output__arr_v4float_uint_16 = OpTypePointer Output %_arr_v4float_uint_16
%out_interpolators = OpVariable %_ptr_Output__arr_v4float_uint_16 Output
%_arr__arr_v4float_uint_16_uint_1 = OpTypeArray %_arr_v4float_uint_16 %uint_1
%_ptr_Input__arr__arr_v4float_uint_16_uint_1 = OpTypePointer Input %_arr__arr_v4float_uint_16_uint_1
%in_interpolators = OpVariable %_ptr_Input__arr__arr_v4float_uint_16_uint_1 Input
%_ptr_Input__arr_v4float_uint_16 = OpTypePointer Input %_arr_v4float_uint_16
%_ptr_Output_v2float = OpTypePointer Output %v2float
%point_coord = OpVariable %_ptr_Output_v2float Output
%108 = OpConstantComposite %v2float %float_0 %float_0
%int_1 = OpConstant %int 1
%_arr_v2float_uint_1 = OpTypeArray %v2float %uint_1
%_ptr_Input__arr_v2float_uint_1 = OpTypePointer Input %_arr_v2float_uint_1
%in_point_coord_unused = OpVariable %_ptr_Input__arr_v2float_uint_1 Input
%main = OpFunction %void None %3
%5 = OpLabel
%indexable = OpVariable %_ptr_Function__arr_v2float_uint_4 Function
%indexable_0 = OpVariable %_ptr_Function__arr_v2float_uint_4 Function
%19 = OpAccessChain %_ptr_Input_v4float %gl_in %int_0 %int_0
%20 = OpLoad %v4float %19
%29 = OpAccessChain %_ptr_PushConstant_v4float %push_constants %int_2
%30 = OpLoad %v4float %29
%31 = OpVectorShuffle %v2float %30 %30 0 1
%36 = OpAccessChain %_ptr_Input_float %point_size %int_0
%37 = OpLoad %float %36
%40 = OpFOrdGreaterThan %bool %37 %float_0
OpSelectionMerge %42 None
OpBranchConditional %40 %41 %42
%41 = OpLabel
%45 = OpCompositeConstruct %v2float %37 %37
OpBranch %42
%42 = OpLabel
%116 = OpPhi %v2float %31 %5 %45 %41
%46 = OpAccessChain %_ptr_PushConstant_v4float %push_constants %int_0
%47 = OpLoad %v4float %46
%48 = OpVectorShuffle %v2float %47 %47 2 3
%50 = OpFDiv %v2float %116 %48
OpBranch %53
%53 = OpLabel
%117 = OpPhi %int %int_0 %42 %112 %54
%60 = OpSLessThan %bool %117 %int_4
OpLoopMerge %55 %54 None
OpBranchConditional %60 %54 %55
%54 = OpLabel
%65 = OpVectorShuffle %v2float %20 %20 0 1
OpStore %indexable %74
%78 = OpAccessChain %_ptr_Function_v2float %indexable %117
%79 = OpLoad %v2float %78
%81 = OpFMul %v2float %79 %50
%82 = OpFAdd %v2float %65 %81
%85 = OpCompositeExtract %float %82 0
%86 = OpCompositeExtract %float %82 1
%87 = OpCompositeExtract %float %20 2
%88 = OpCompositeExtract %float %20 3
%89 = OpCompositeConstruct %v4float %85 %86 %87 %88
%91 = OpAccessChain %_ptr_Output_v4float %_ %int_0
OpStore %91 %89
%100 = OpAccessChain %_ptr_Input__arr_v4float_uint_16 %in_interpolators %int_0
%101 = OpLoad %_arr_v4float_uint_16 %100
OpStore %out_interpolators %101
OpStore %indexable_0 %74
%106 = OpAccessChain %_ptr_Function_v2float %indexable_0 %117
%107 = OpLoad %v2float %106
%109 = OpExtInst %v2float %1 FMax %107 %108
OpStore %point_coord %109
OpEmitVertex
%112 = OpIAdd %int %117 %int_1
OpBranch %53
%55 = OpLabel
OpEndPrimitive
OpReturn
OpFunctionEnd

View File

@@ -1,171 +0,0 @@
// generated from `xb genspirv`
// source: quad_list.geom
const uint8_t quad_list_geom[] = {
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x08, 0x00,
0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x18, 0x00, 0x00, 0x00,
0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00,
0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x0C, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
0x28, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00,
0x45, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00,
0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x10, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00,
0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,
0x02, 0x00, 0x00, 0x00, 0xC2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00,
0x47, 0x4C, 0x5F, 0x41, 0x52, 0x42, 0x5F, 0x65, 0x78, 0x70, 0x6C, 0x69,
0x63, 0x69, 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x5F, 0x6C,
0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x04, 0x00, 0x09, 0x00,
0x47, 0x4C, 0x5F, 0x41, 0x52, 0x42, 0x5F, 0x73, 0x65, 0x70, 0x61, 0x72,
0x61, 0x74, 0x65, 0x5F, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5F, 0x6F,
0x62, 0x6A, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00,
0x47, 0x4C, 0x5F, 0x41, 0x52, 0x42, 0x5F, 0x73, 0x68, 0x61, 0x64, 0x69,
0x6E, 0x67, 0x5F, 0x6C, 0x61, 0x6E, 0x67, 0x75, 0x61, 0x67, 0x65, 0x5F,
0x34, 0x32, 0x30, 0x70, 0x61, 0x63, 0x6B, 0x00, 0x05, 0x00, 0x04, 0x00,
0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x05, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x64, 0x65,
0x78, 0x61, 0x62, 0x6C, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00,
0x22, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, 0x65, 0x72, 0x56, 0x65,
0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00,
0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50,
0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x06, 0x00, 0x07, 0x00,
0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50,
0x6F, 0x69, 0x6E, 0x74, 0x53, 0x69, 0x7A, 0x65, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x03, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x06, 0x00, 0x25, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50,
0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x06, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x00,
0x06, 0x00, 0x07, 0x00, 0x25, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x53, 0x69, 0x7A, 0x65,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00,
0x67, 0x6C, 0x5F, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x05, 0x00, 0x07, 0x00,
0x38, 0x00, 0x00, 0x00, 0x6F, 0x75, 0x74, 0x5F, 0x69, 0x6E, 0x74, 0x65,
0x72, 0x70, 0x6F, 0x6C, 0x61, 0x74, 0x6F, 0x72, 0x73, 0x00, 0x00, 0x00,
0x05, 0x00, 0x07, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x69, 0x6E, 0x5F, 0x69,
0x6E, 0x74, 0x65, 0x72, 0x70, 0x6F, 0x6C, 0x61, 0x74, 0x6F, 0x72, 0x73,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0x45, 0x00, 0x00, 0x00,
0x5F, 0x69, 0x6E, 0x5F, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x5F, 0x63, 0x6F,
0x6F, 0x72, 0x64, 0x5F, 0x75, 0x6E, 0x75, 0x73, 0x65, 0x64, 0x00, 0x00,
0x05, 0x00, 0x08, 0x00, 0x48, 0x00, 0x00, 0x00, 0x5F, 0x69, 0x6E, 0x5F,
0x70, 0x6F, 0x69, 0x6E, 0x74, 0x5F, 0x73, 0x69, 0x7A, 0x65, 0x5F, 0x75,
0x6E, 0x75, 0x73, 0x65, 0x64, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00,
0x4A, 0x00, 0x00, 0x00, 0x5F, 0x6F, 0x75, 0x74, 0x5F, 0x70, 0x6F, 0x69,
0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x5F, 0x75, 0x6E, 0x75,
0x73, 0x65, 0x64, 0x00, 0x48, 0x00, 0x05, 0x00, 0x22, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x48, 0x00, 0x05, 0x00, 0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00,
0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x47, 0x00, 0x03, 0x00, 0x25, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x3B, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
0x45, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0x48, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x11, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x4A, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00,
0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00,
0x11, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
0x17, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x07, 0x00, 0x16, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
0x16, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x17, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00,
0x21, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x23, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00,
0x21, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00,
0x26, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x26, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00,
0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x2A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x21, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x30, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x33, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x36, 0x00, 0x00, 0x00,
0x21, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x37, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x37, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x39, 0x00, 0x00, 0x00,
0x36, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x3A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
0x42, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x04, 0x00, 0x43, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x44, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
0x44, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x04, 0x00, 0x46, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x15, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x47, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
0x47, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x49, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x42, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x49, 0x00, 0x00, 0x00,
0x4A, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00,
0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x07, 0x00,
0x06, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
0xB1, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
0x4B, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xF6, 0x00, 0x04, 0x00,
0x0C, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFA, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x1D, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x41, 0x00, 0x06, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00,
0x28, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x2D, 0x00, 0x00, 0x00,
0x2E, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,
0x41, 0x00, 0x06, 0x00, 0x30, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00,
0x28, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
0x31, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x33, 0x00, 0x00, 0x00,
0x34, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x34, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x36, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00,
0xDA, 0x00, 0x01, 0x00, 0x80, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
0x41, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
0xF9, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
0x0C, 0x00, 0x00, 0x00, 0xDB, 0x00, 0x01, 0x00, 0xFD, 0x00, 0x01, 0x00,
0x38, 0x00, 0x01, 0x00,
};

View File

@@ -1,120 +0,0 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 6
; Bound: 76
; Schema: 0
OpCapability Geometry
OpCapability GeometryPointSize
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Geometry %main "main" %_ %gl_in %out_interpolators %in_interpolators %_in_point_coord_unused %_in_point_size_unused %_out_point_coord_unused
OpExecutionMode %main InputLinesAdjacency
OpExecutionMode %main Invocations 1
OpExecutionMode %main OutputTriangleStrip
OpExecutionMode %main OutputVertices 4
OpSource GLSL 450
OpSourceExtension "GL_ARB_explicit_attrib_location"
OpSourceExtension "GL_ARB_separate_shader_objects"
OpSourceExtension "GL_ARB_shading_language_420pack"
OpName %main "main"
OpName %indexable "indexable"
OpName %gl_PerVertex "gl_PerVertex"
OpMemberName %gl_PerVertex 0 "gl_Position"
OpMemberName %gl_PerVertex 1 "gl_PointSize"
OpName %_ ""
OpName %gl_PerVertex_0 "gl_PerVertex"
OpMemberName %gl_PerVertex_0 0 "gl_Position"
OpMemberName %gl_PerVertex_0 1 "gl_PointSize"
OpName %gl_in "gl_in"
OpName %out_interpolators "out_interpolators"
OpName %in_interpolators "in_interpolators"
OpName %_in_point_coord_unused "_in_point_coord_unused"
OpName %_in_point_size_unused "_in_point_size_unused"
OpName %_out_point_coord_unused "_out_point_coord_unused"
OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
OpDecorate %gl_PerVertex Block
OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
OpDecorate %gl_PerVertex_0 Block
OpDecorate %out_interpolators Location 0
OpDecorate %in_interpolators Location 0
OpDecorate %_in_point_coord_unused Location 16
OpDecorate %_in_point_size_unused Location 17
OpDecorate %_out_point_coord_unused Location 16
%void = OpTypeVoid
%3 = OpTypeFunction %void
%int = OpTypeInt 32 1
%_ptr_Function_int = OpTypePointer Function %int
%int_0 = OpConstant %int 0
%int_4 = OpConstant %int 4
%bool = OpTypeBool
%uint = OpTypeInt 32 0
%uint_4 = OpConstant %uint 4
%_arr_int_uint_4 = OpTypeArray %int %uint_4
%int_1 = OpConstant %int 1
%int_3 = OpConstant %int 3
%int_2 = OpConstant %int 2
%26 = OpConstantComposite %_arr_int_uint_4 %int_0 %int_1 %int_3 %int_2
%_ptr_Function__arr_int_uint_4 = OpTypePointer Function %_arr_int_uint_4
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%gl_PerVertex = OpTypeStruct %v4float %float
%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
%_ = OpVariable %_ptr_Output_gl_PerVertex Output
%gl_PerVertex_0 = OpTypeStruct %v4float %float
%_arr_gl_PerVertex_0_uint_4 = OpTypeArray %gl_PerVertex_0 %uint_4
%_ptr_Input__arr_gl_PerVertex_0_uint_4 = OpTypePointer Input %_arr_gl_PerVertex_0_uint_4
%gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_0_uint_4 Input
%_ptr_Input_v4float = OpTypePointer Input %v4float
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_ptr_Input_float = OpTypePointer Input %float
%_ptr_Output_float = OpTypePointer Output %float
%uint_16 = OpConstant %uint 16
%_arr_v4float_uint_16 = OpTypeArray %v4float %uint_16
%_ptr_Output__arr_v4float_uint_16 = OpTypePointer Output %_arr_v4float_uint_16
%out_interpolators = OpVariable %_ptr_Output__arr_v4float_uint_16 Output
%_arr__arr_v4float_uint_16_uint_4 = OpTypeArray %_arr_v4float_uint_16 %uint_4
%_ptr_Input__arr__arr_v4float_uint_16_uint_4 = OpTypePointer Input %_arr__arr_v4float_uint_16_uint_4
%in_interpolators = OpVariable %_ptr_Input__arr__arr_v4float_uint_16_uint_4 Input
%_ptr_Input__arr_v4float_uint_16 = OpTypePointer Input %_arr_v4float_uint_16
%v2float = OpTypeVector %float 2
%_arr_v2float_uint_4 = OpTypeArray %v2float %uint_4
%_ptr_Input__arr_v2float_uint_4 = OpTypePointer Input %_arr_v2float_uint_4
%_in_point_coord_unused = OpVariable %_ptr_Input__arr_v2float_uint_4 Input
%_arr_float_uint_4 = OpTypeArray %float %uint_4
%_ptr_Input__arr_float_uint_4 = OpTypePointer Input %_arr_float_uint_4
%_in_point_size_unused = OpVariable %_ptr_Input__arr_float_uint_4 Input
%_ptr_Output_v2float = OpTypePointer Output %v2float
%_out_point_coord_unused = OpVariable %_ptr_Output_v2float Output
%main = OpFunction %void None %3
%5 = OpLabel
%indexable = OpVariable %_ptr_Function__arr_int_uint_4 Function
OpBranch %10
%10 = OpLabel
%75 = OpPhi %int %int_0 %5 %65 %11
%18 = OpSLessThan %bool %75 %int_4
OpLoopMerge %12 %11 None
OpBranchConditional %18 %11 %12
%11 = OpLabel
OpStore %indexable %26
%30 = OpAccessChain %_ptr_Function_int %indexable %75
%31 = OpLoad %int %30
%43 = OpAccessChain %_ptr_Input_v4float %gl_in %31 %int_0
%44 = OpLoad %v4float %43
%46 = OpAccessChain %_ptr_Output_v4float %_ %int_0
OpStore %46 %44
%49 = OpAccessChain %_ptr_Input_float %gl_in %31 %int_1
%50 = OpLoad %float %49
%52 = OpAccessChain %_ptr_Output_float %_ %int_1
OpStore %52 %50
%62 = OpAccessChain %_ptr_Input__arr_v4float_uint_16 %in_interpolators %31
%63 = OpLoad %_arr_v4float_uint_16 %62
OpStore %out_interpolators %63
OpEmitVertex
%65 = OpIAdd %int %75 %int_1
OpBranch %10
%12 = OpLabel
OpEndPrimitive
OpReturn
OpFunctionEnd

View File

@@ -1,374 +0,0 @@
// generated from `xb genspirv`
// source: rect_list.geom
const uint8_t rect_list_geom[] = {
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0x08, 0x00,
0x28, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
0x02, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x18, 0x00, 0x00, 0x00,
0x0B, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4C, 0x53, 0x4C,
0x2E, 0x73, 0x74, 0x64, 0x2E, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00,
0x0E, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x0C, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0x4C, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00,
0x0C, 0x01, 0x00, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00,
0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
0x10, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00,
0x1D, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,
0x1A, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,
0x02, 0x00, 0x00, 0x00, 0xC2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x09, 0x00,
0x47, 0x4C, 0x5F, 0x41, 0x52, 0x42, 0x5F, 0x65, 0x78, 0x70, 0x6C, 0x69,
0x63, 0x69, 0x74, 0x5F, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x5F, 0x6C,
0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x04, 0x00, 0x09, 0x00,
0x47, 0x4C, 0x5F, 0x41, 0x52, 0x42, 0x5F, 0x73, 0x65, 0x70, 0x61, 0x72,
0x61, 0x74, 0x65, 0x5F, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5F, 0x6F,
0x62, 0x6A, 0x65, 0x63, 0x74, 0x73, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
0x04, 0x00, 0x00, 0x00, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x06, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50,
0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00,
0x06, 0x00, 0x06, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x00,
0x06, 0x00, 0x07, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x67, 0x6C, 0x5F, 0x50, 0x6F, 0x69, 0x6E, 0x74, 0x53, 0x69, 0x7A, 0x65,
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00,
0x67, 0x6C, 0x5F, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00,
0x4A, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50, 0x65, 0x72, 0x56, 0x65,
0x72, 0x74, 0x65, 0x78, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00,
0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50,
0x6F, 0x73, 0x69, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x06, 0x00, 0x07, 0x00,
0x4A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x67, 0x6C, 0x5F, 0x50,
0x6F, 0x69, 0x6E, 0x74, 0x53, 0x69, 0x7A, 0x65, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x03, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x05, 0x00, 0x07, 0x00, 0x58, 0x00, 0x00, 0x00, 0x6F, 0x75, 0x74, 0x5F,
0x69, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x6F, 0x6C, 0x61, 0x74, 0x6F, 0x72,
0x73, 0x00, 0x00, 0x00, 0x05, 0x00, 0x07, 0x00, 0x5B, 0x00, 0x00, 0x00,
0x69, 0x6E, 0x5F, 0x69, 0x6E, 0x74, 0x65, 0x72, 0x70, 0x6F, 0x6C, 0x61,
0x74, 0x6F, 0x72, 0x73, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00,
0x0C, 0x01, 0x00, 0x00, 0x5F, 0x69, 0x6E, 0x5F, 0x70, 0x6F, 0x69, 0x6E,
0x74, 0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64, 0x5F, 0x75, 0x6E, 0x75, 0x73,
0x65, 0x64, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0x0F, 0x01, 0x00, 0x00,
0x5F, 0x69, 0x6E, 0x5F, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x5F, 0x73, 0x69,
0x7A, 0x65, 0x5F, 0x75, 0x6E, 0x75, 0x73, 0x65, 0x64, 0x00, 0x00, 0x00,
0x05, 0x00, 0x08, 0x00, 0x11, 0x01, 0x00, 0x00, 0x5F, 0x6F, 0x75, 0x74,
0x5F, 0x70, 0x6F, 0x69, 0x6E, 0x74, 0x5F, 0x63, 0x6F, 0x6F, 0x72, 0x64,
0x5F, 0x75, 0x6E, 0x75, 0x73, 0x65, 0x64, 0x00, 0x48, 0x00, 0x05, 0x00,
0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1D, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x47, 0x00, 0x03, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x48, 0x00, 0x05, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
0x4A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x4A, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x58, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
0x5B, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x47, 0x00, 0x04, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0F, 0x01, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
0x11, 0x01, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00,
0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00,
0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x14, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
0x17, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x17, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x04, 0x00, 0x1D, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00,
0x1D, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
0x23, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x27, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00, 0x1E, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x6F, 0x12, 0x83, 0x3A,
0x20, 0x00, 0x04, 0x00, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x04, 0x00, 0x4A, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x4B, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x4B, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x4F, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x53, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x04, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,
0x10, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x56, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x57, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x57, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x04, 0x00, 0x59, 0x00, 0x00, 0x00,
0x56, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
0x5A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x04, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x5C, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x04, 0x00,
0x23, 0x00, 0x00, 0x00, 0x9F, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x04, 0x00, 0x0A, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x1F, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0B, 0x01, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0A, 0x01, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
0x0B, 0x01, 0x00, 0x00, 0x0C, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x1C, 0x00, 0x04, 0x00, 0x0D, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x1F, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0E, 0x01, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x0D, 0x01, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00,
0x0E, 0x01, 0x00, 0x00, 0x0F, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x20, 0x00, 0x04, 0x00, 0x10, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x04, 0x00, 0x10, 0x01, 0x00, 0x00,
0x11, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x05, 0x00,
0x07, 0x00, 0x00, 0x00, 0x25, 0x01, 0x00, 0x00, 0x2F, 0x00, 0x00, 0x00,
0x2F, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00,
0x27, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0x25, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
0x28, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0x27, 0x00, 0x00, 0x00,
0x2C, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00,
0x50, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00,
0x29, 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
0x31, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
0x4F, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0x33, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00,
0x16, 0x01, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x06, 0x00, 0x07, 0x00, 0x00, 0x00, 0x17, 0x01, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x16, 0x01, 0x00, 0x00,
0xBC, 0x00, 0x05, 0x00, 0x17, 0x00, 0x00, 0x00, 0x1A, 0x01, 0x00, 0x00,
0x17, 0x01, 0x00, 0x00, 0x25, 0x01, 0x00, 0x00, 0x9B, 0x00, 0x04, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x1B, 0x01, 0x00, 0x00, 0x1A, 0x01, 0x00, 0x00,
0xA8, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
0x1B, 0x01, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00, 0x3A, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00, 0x38, 0x00, 0x00, 0x00,
0x39, 0x00, 0x00, 0x00, 0x3A, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
0x39, 0x00, 0x00, 0x00, 0x41, 0x00, 0x07, 0x00, 0x27, 0x00, 0x00, 0x00,
0x3B, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00,
0x41, 0x00, 0x07, 0x00, 0x27, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00,
0x22, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
0x2B, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x50, 0x00, 0x05, 0x00,
0x07, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00,
0x1F, 0x01, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x06, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1F, 0x01, 0x00, 0x00,
0xBC, 0x00, 0x05, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x01, 0x00, 0x00,
0x20, 0x01, 0x00, 0x00, 0x25, 0x01, 0x00, 0x00, 0x9B, 0x00, 0x04, 0x00,
0x0A, 0x00, 0x00, 0x00, 0x24, 0x01, 0x00, 0x00, 0x23, 0x01, 0x00, 0x00,
0xF9, 0x00, 0x02, 0x00, 0x3A, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
0x3A, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00,
0x47, 0x00, 0x00, 0x00, 0x1B, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x24, 0x01, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0xF7, 0x00, 0x03, 0x00,
0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00,
0x47, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0xB1, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x02, 0x00, 0x48, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
0x4F, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x50, 0x00, 0x00, 0x00,
0x33, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x27, 0x00, 0x00, 0x00,
0x51, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
0x2A, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
0x52, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
0x53, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00,
0x2A, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x54, 0x00, 0x00, 0x00,
0x52, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x5C, 0x00, 0x00, 0x00,
0x5D, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x56, 0x00, 0x00, 0x00, 0x5E, 0x00, 0x00, 0x00,
0x5D, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x58, 0x00, 0x00, 0x00,
0x5E, 0x00, 0x00, 0x00, 0xDA, 0x00, 0x01, 0x00, 0x41, 0x00, 0x06, 0x00,
0x31, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0x2A, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x50, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
0x41, 0x00, 0x06, 0x00, 0x27, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00,
0x22, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00,
0x62, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x54, 0x00, 0x00, 0x00,
0x63, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x5C, 0x00, 0x00, 0x00,
0x65, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x56, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00,
0x65, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x58, 0x00, 0x00, 0x00,
0x66, 0x00, 0x00, 0x00, 0xDA, 0x00, 0x01, 0x00, 0x41, 0x00, 0x06, 0x00,
0x31, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0x25, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x50, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00,
0x41, 0x00, 0x06, 0x00, 0x27, 0x00, 0x00, 0x00, 0x6A, 0x00, 0x00, 0x00,
0x22, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x00,
0x6A, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x54, 0x00, 0x00, 0x00,
0x6B, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x5C, 0x00, 0x00, 0x00,
0x6D, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x56, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x00, 0x00,
0x6D, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x58, 0x00, 0x00, 0x00,
0x6E, 0x00, 0x00, 0x00, 0xDA, 0x00, 0x01, 0x00, 0xDB, 0x00, 0x01, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x50, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x54, 0x00, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x58, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x00, 0x00,
0xDA, 0x00, 0x01, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x50, 0x00, 0x00, 0x00,
0x60, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x54, 0x00, 0x00, 0x00,
0x63, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x58, 0x00, 0x00, 0x00,
0x66, 0x00, 0x00, 0x00, 0xDA, 0x00, 0x01, 0x00, 0x7F, 0x00, 0x04, 0x00,
0x07, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0x4F, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00,
0x60, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00,
0x86, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00,
0x4F, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00,
0x8A, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00,
0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x8E, 0x00, 0x00, 0x00,
0x8A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00,
0x06, 0x00, 0x00, 0x00, 0x8F, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
0x90, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x8E, 0x00, 0x00, 0x00,
0x8F, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x50, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0x54, 0x00, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x00,
0xF9, 0x00, 0x02, 0x00, 0x99, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
0x99, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x07, 0x00, 0x23, 0x00, 0x00, 0x00,
0x27, 0x01, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
0xB0, 0x00, 0x00, 0x00, 0x9A, 0x00, 0x00, 0x00, 0xB1, 0x00, 0x05, 0x00,
0x0A, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x27, 0x01, 0x00, 0x00,
0x9F, 0x00, 0x00, 0x00, 0xF6, 0x00, 0x04, 0x00, 0x9B, 0x00, 0x00, 0x00,
0x9A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x04, 0x00,
0xA0, 0x00, 0x00, 0x00, 0x9A, 0x00, 0x00, 0x00, 0x9B, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x02, 0x00, 0x9A, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
0x31, 0x00, 0x00, 0x00, 0xA3, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x27, 0x01, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x1C, 0x00, 0x00, 0x00, 0xA4, 0x00, 0x00, 0x00, 0xA3, 0x00, 0x00, 0x00,
0x7F, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xA5, 0x00, 0x00, 0x00,
0xA4, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00,
0xA7, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0x27, 0x01, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00,
0xA8, 0x00, 0x00, 0x00, 0xA7, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
0x1C, 0x00, 0x00, 0x00, 0xA9, 0x00, 0x00, 0x00, 0xA5, 0x00, 0x00, 0x00,
0xA8, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00,
0xAB, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
0x27, 0x01, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00,
0xAC, 0x00, 0x00, 0x00, 0xAB, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
0x1C, 0x00, 0x00, 0x00, 0xAD, 0x00, 0x00, 0x00, 0xA9, 0x00, 0x00, 0x00,
0xAC, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x4F, 0x00, 0x00, 0x00,
0xAE, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x27, 0x01, 0x00, 0x00,
0x3E, 0x00, 0x03, 0x00, 0xAE, 0x00, 0x00, 0x00, 0xAD, 0x00, 0x00, 0x00,
0x80, 0x00, 0x05, 0x00, 0x23, 0x00, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00,
0x27, 0x01, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00,
0x99, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0x9B, 0x00, 0x00, 0x00,
0xDA, 0x00, 0x01, 0x00, 0xDB, 0x00, 0x01, 0x00, 0xF9, 0x00, 0x02, 0x00,
0x49, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0xB1, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x4F, 0x00, 0x00, 0x00, 0xB4, 0x00, 0x00, 0x00,
0x4C, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0xB4, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
0x27, 0x00, 0x00, 0x00, 0xB5, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x06, 0x00, 0x00, 0x00, 0xB6, 0x00, 0x00, 0x00, 0xB5, 0x00, 0x00, 0x00,
0x41, 0x00, 0x05, 0x00, 0x53, 0x00, 0x00, 0x00, 0xB7, 0x00, 0x00, 0x00,
0x4C, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0xB7, 0x00, 0x00, 0x00, 0xB6, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
0x5C, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x56, 0x00, 0x00, 0x00,
0xB9, 0x00, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0x58, 0x00, 0x00, 0x00, 0xB9, 0x00, 0x00, 0x00, 0xDA, 0x00, 0x01, 0x00,
0x41, 0x00, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00, 0xBA, 0x00, 0x00, 0x00,
0x22, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00,
0xBA, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0xB4, 0x00, 0x00, 0x00,
0xBB, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x27, 0x00, 0x00, 0x00,
0xBD, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0x2A, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
0xBE, 0x00, 0x00, 0x00, 0xBD, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0xB7, 0x00, 0x00, 0x00, 0xBE, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
0x5C, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00,
0x2A, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x56, 0x00, 0x00, 0x00,
0xC1, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0x58, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x00, 0x00, 0xDA, 0x00, 0x01, 0x00,
0x41, 0x00, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00, 0xC2, 0x00, 0x00, 0x00,
0x22, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x00, 0x00,
0xC2, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0xB4, 0x00, 0x00, 0x00,
0xC3, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x27, 0x00, 0x00, 0x00,
0xC5, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
0x2A, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00,
0xC6, 0x00, 0x00, 0x00, 0xC5, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0xB7, 0x00, 0x00, 0x00, 0xC6, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
0x5C, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00,
0x25, 0x00, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x56, 0x00, 0x00, 0x00,
0xC9, 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0x58, 0x00, 0x00, 0x00, 0xC9, 0x00, 0x00, 0x00, 0xDA, 0x00, 0x01, 0x00,
0xDB, 0x00, 0x01, 0x00, 0x3E, 0x00, 0x03, 0x00, 0xB4, 0x00, 0x00, 0x00,
0x33, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0xB7, 0x00, 0x00, 0x00,
0xB6, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x58, 0x00, 0x00, 0x00,
0xB9, 0x00, 0x00, 0x00, 0xDA, 0x00, 0x01, 0x00, 0x3E, 0x00, 0x03, 0x00,
0xB4, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0xB7, 0x00, 0x00, 0x00, 0xC6, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00,
0x58, 0x00, 0x00, 0x00, 0xC9, 0x00, 0x00, 0x00, 0xDA, 0x00, 0x01, 0x00,
0x4F, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0xDF, 0x00, 0x00, 0x00,
0xBB, 0x00, 0x00, 0x00, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
0xE0, 0x00, 0x00, 0x00, 0xDF, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
0x07, 0x00, 0x00, 0x00, 0xE1, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0xE0, 0x00, 0x00, 0x00, 0x4F, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00,
0xE4, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00,
0x07, 0x00, 0x00, 0x00, 0xE5, 0x00, 0x00, 0x00, 0xE1, 0x00, 0x00, 0x00,
0xE4, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
0xE9, 0x00, 0x00, 0x00, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xEA, 0x00, 0x00, 0x00,
0xE5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00,
0x06, 0x00, 0x00, 0x00, 0xEB, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
0xEC, 0x00, 0x00, 0x00, 0xC3, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x50, 0x00, 0x07, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xED, 0x00, 0x00, 0x00,
0xE9, 0x00, 0x00, 0x00, 0xEA, 0x00, 0x00, 0x00, 0xEB, 0x00, 0x00, 0x00,
0xEC, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0xB4, 0x00, 0x00, 0x00,
0xED, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0xB7, 0x00, 0x00, 0x00,
0xC6, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x02, 0x00, 0xF3, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x02, 0x00, 0xF3, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x07, 0x00,
0x23, 0x00, 0x00, 0x00, 0x26, 0x01, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
0xB1, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0xF4, 0x00, 0x00, 0x00,
0xB1, 0x00, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x00, 0xF9, 0x00, 0x00, 0x00,
0x26, 0x01, 0x00, 0x00, 0x9F, 0x00, 0x00, 0x00, 0xF6, 0x00, 0x04, 0x00,
0xF5, 0x00, 0x00, 0x00, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFA, 0x00, 0x04, 0x00, 0xF9, 0x00, 0x00, 0x00, 0xF4, 0x00, 0x00, 0x00,
0xF5, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00, 0xF4, 0x00, 0x00, 0x00,
0x41, 0x00, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00,
0x5B, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x26, 0x01, 0x00, 0x00,
0x3D, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x00, 0x00,
0xFC, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00,
0xFF, 0x00, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0x26, 0x01, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00, 0x1C, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x04, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
0x81, 0x00, 0x05, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
0xFD, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00,
0x31, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x5B, 0x00, 0x00, 0x00,
0x25, 0x00, 0x00, 0x00, 0x26, 0x01, 0x00, 0x00, 0x3D, 0x00, 0x04, 0x00,
0x1C, 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
0x81, 0x00, 0x05, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00,
0x02, 0x01, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
0x4F, 0x00, 0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
0x26, 0x01, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0x07, 0x01, 0x00, 0x00,
0x06, 0x01, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x23, 0x00, 0x00, 0x00,
0x09, 0x01, 0x00, 0x00, 0x26, 0x01, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x00,
0xF9, 0x00, 0x02, 0x00, 0xF3, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
0xF5, 0x00, 0x00, 0x00, 0xDA, 0x00, 0x01, 0x00, 0xDB, 0x00, 0x01, 0x00,
0xF9, 0x00, 0x02, 0x00, 0x49, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x02, 0x00,
0x49, 0x00, 0x00, 0x00, 0xFD, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00,
};

View File

@@ -1,274 +0,0 @@
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 6
; Bound: 296
; Schema: 0
OpCapability Geometry
OpCapability GeometryPointSize
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Geometry %main "main" %gl_in %_ %out_interpolators %in_interpolators %_in_point_coord_unused %_in_point_size_unused %_out_point_coord_unused
OpExecutionMode %main Triangles
OpExecutionMode %main Invocations 1
OpExecutionMode %main OutputTriangleStrip
OpExecutionMode %main OutputVertices 6
OpSource GLSL 450
OpSourceExtension "GL_ARB_explicit_attrib_location"
OpSourceExtension "GL_ARB_separate_shader_objects"
OpName %main "main"
OpName %gl_PerVertex "gl_PerVertex"
OpMemberName %gl_PerVertex 0 "gl_Position"
OpMemberName %gl_PerVertex 1 "gl_PointSize"
OpName %gl_in "gl_in"
OpName %gl_PerVertex_0 "gl_PerVertex"
OpMemberName %gl_PerVertex_0 0 "gl_Position"
OpMemberName %gl_PerVertex_0 1 "gl_PointSize"
OpName %_ ""
OpName %out_interpolators "out_interpolators"
OpName %in_interpolators "in_interpolators"
OpName %_in_point_coord_unused "_in_point_coord_unused"
OpName %_in_point_size_unused "_in_point_size_unused"
OpName %_out_point_coord_unused "_out_point_coord_unused"
OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
OpDecorate %gl_PerVertex Block
OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
OpDecorate %gl_PerVertex_0 Block
OpDecorate %out_interpolators Location 0
OpDecorate %in_interpolators Location 0
OpDecorate %_in_point_coord_unused Location 16
OpDecorate %_in_point_size_unused Location 17
OpDecorate %_out_point_coord_unused Location 16
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v2float = OpTypeVector %float 2
%bool = OpTypeBool
%v2bool = OpTypeVector %bool 2
%v4float = OpTypeVector %float 4
%gl_PerVertex = OpTypeStruct %v4float %float
%uint = OpTypeInt 32 0
%uint_3 = OpConstant %uint 3
%_arr_gl_PerVertex_uint_3 = OpTypeArray %gl_PerVertex %uint_3
%_ptr_Input__arr_gl_PerVertex_uint_3 = OpTypePointer Input %_arr_gl_PerVertex_uint_3
%gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_uint_3 Input
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%int_2 = OpConstant %int 2
%uint_0 = OpConstant %uint 0
%_ptr_Input_float = OpTypePointer Input %float
%int_1 = OpConstant %int 1
%uint_1 = OpConstant %uint 1
%float_0_00100000005 = OpConstant %float 0.00100000005
%_ptr_Input_v4float = OpTypePointer Input %v4float
%gl_PerVertex_0 = OpTypeStruct %v4float %float
%_ptr_Output_gl_PerVertex_0 = OpTypePointer Output %gl_PerVertex_0
%_ = OpVariable %_ptr_Output_gl_PerVertex_0 Output
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_ptr_Output_float = OpTypePointer Output %float
%uint_16 = OpConstant %uint 16
%_arr_v4float_uint_16 = OpTypeArray %v4float %uint_16
%_ptr_Output__arr_v4float_uint_16 = OpTypePointer Output %_arr_v4float_uint_16
%out_interpolators = OpVariable %_ptr_Output__arr_v4float_uint_16 Output
%_arr__arr_v4float_uint_16_uint_3 = OpTypeArray %_arr_v4float_uint_16 %uint_3
%_ptr_Input__arr__arr_v4float_uint_16_uint_3 = OpTypePointer Input %_arr__arr_v4float_uint_16_uint_3
%in_interpolators = OpVariable %_ptr_Input__arr__arr_v4float_uint_16_uint_3 Input
%_ptr_Input__arr_v4float_uint_16 = OpTypePointer Input %_arr_v4float_uint_16
%int_16 = OpConstant %int 16
%_arr_v2float_uint_3 = OpTypeArray %v2float %uint_3
%_ptr_Input__arr_v2float_uint_3 = OpTypePointer Input %_arr_v2float_uint_3
%_in_point_coord_unused = OpVariable %_ptr_Input__arr_v2float_uint_3 Input
%_arr_float_uint_3 = OpTypeArray %float %uint_3
%_ptr_Input__arr_float_uint_3 = OpTypePointer Input %_arr_float_uint_3
%_in_point_size_unused = OpVariable %_ptr_Input__arr_float_uint_3 Input
%_ptr_Output_v2float = OpTypePointer Output %v2float
%_out_point_coord_unused = OpVariable %_ptr_Output_v2float Output
%293 = OpConstantComposite %v2float %float_0_00100000005 %float_0_00100000005
%main = OpFunction %void None %3
%5 = OpLabel
%40 = OpAccessChain %_ptr_Input_float %gl_in %int_2 %int_0 %uint_0
%41 = OpLoad %float %40
%44 = OpAccessChain %_ptr_Input_float %gl_in %int_1 %int_0 %uint_1
%45 = OpLoad %float %44
%46 = OpCompositeConstruct %v2float %41 %45
%50 = OpAccessChain %_ptr_Input_v4float %gl_in %int_0 %int_0
%51 = OpLoad %v4float %50
%52 = OpVectorShuffle %v2float %51 %51 0 1
%278 = OpFSub %v2float %52 %46
%279 = OpExtInst %v2float %1 FAbs %278
%282 = OpFOrdLessThanEqual %v2bool %279 %293
%283 = OpAll %bool %282
%56 = OpLogicalNot %bool %283
OpSelectionMerge %58 None
OpBranchConditional %56 %57 %58
%57 = OpLabel
%59 = OpAccessChain %_ptr_Input_float %gl_in %int_1 %int_0 %uint_0
%60 = OpLoad %float %59
%61 = OpAccessChain %_ptr_Input_float %gl_in %int_2 %int_0 %uint_1
%62 = OpLoad %float %61
%63 = OpCompositeConstruct %v2float %60 %62
%287 = OpFSub %v2float %52 %63
%288 = OpExtInst %v2float %1 FAbs %287
%291 = OpFOrdLessThanEqual %v2bool %288 %293
%292 = OpAll %bool %291
OpBranch %58
%58 = OpLabel
%71 = OpPhi %bool %283 %5 %292 %57
OpSelectionMerge %73 None
OpBranchConditional %71 %72 %177
%72 = OpLabel
%80 = OpAccessChain %_ptr_Output_v4float %_ %int_0
OpStore %80 %51
%81 = OpAccessChain %_ptr_Input_float %gl_in %int_0 %int_1
%82 = OpLoad %float %81
%84 = OpAccessChain %_ptr_Output_float %_ %int_1
OpStore %84 %82
%93 = OpAccessChain %_ptr_Input__arr_v4float_uint_16 %in_interpolators %int_0
%94 = OpLoad %_arr_v4float_uint_16 %93
OpStore %out_interpolators %94
OpEmitVertex
%95 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0
%96 = OpLoad %v4float %95
OpStore %80 %96
%98 = OpAccessChain %_ptr_Input_float %gl_in %int_1 %int_1
%99 = OpLoad %float %98
OpStore %84 %99
%101 = OpAccessChain %_ptr_Input__arr_v4float_uint_16 %in_interpolators %int_1
%102 = OpLoad %_arr_v4float_uint_16 %101
OpStore %out_interpolators %102
OpEmitVertex
%103 = OpAccessChain %_ptr_Input_v4float %gl_in %int_2 %int_0
%104 = OpLoad %v4float %103
OpStore %80 %104
%106 = OpAccessChain %_ptr_Input_float %gl_in %int_2 %int_1
%107 = OpLoad %float %106
OpStore %84 %107
%109 = OpAccessChain %_ptr_Input__arr_v4float_uint_16 %in_interpolators %int_2
%110 = OpLoad %_arr_v4float_uint_16 %109
OpStore %out_interpolators %110
OpEmitVertex
OpEndPrimitive
OpStore %80 %104
OpStore %84 %107
OpStore %out_interpolators %110
OpEmitVertex
OpStore %80 %96
OpStore %84 %99
OpStore %out_interpolators %102
OpEmitVertex
%130 = OpFNegate %v2float %52
%133 = OpVectorShuffle %v2float %96 %96 0 1
%134 = OpFAdd %v2float %130 %133
%137 = OpVectorShuffle %v2float %104 %104 0 1
%138 = OpFAdd %v2float %134 %137
%142 = OpCompositeExtract %float %138 0
%143 = OpCompositeExtract %float %138 1
%144 = OpCompositeExtract %float %104 2
%145 = OpCompositeExtract %float %104 3
%146 = OpCompositeConstruct %v4float %142 %143 %144 %145
OpStore %80 %146
OpStore %84 %107
OpBranch %153
%153 = OpLabel
%295 = OpPhi %int %int_0 %72 %176 %154
%160 = OpSLessThan %bool %295 %int_16
OpLoopMerge %155 %154 None
OpBranchConditional %160 %154 %155
%154 = OpLabel
%163 = OpAccessChain %_ptr_Input_v4float %in_interpolators %int_0 %295
%164 = OpLoad %v4float %163
%165 = OpFNegate %v4float %164
%167 = OpAccessChain %_ptr_Input_v4float %in_interpolators %int_1 %295
%168 = OpLoad %v4float %167
%169 = OpFAdd %v4float %165 %168
%171 = OpAccessChain %_ptr_Input_v4float %in_interpolators %int_2 %295
%172 = OpLoad %v4float %171
%173 = OpFAdd %v4float %169 %172
%174 = OpAccessChain %_ptr_Output_v4float %out_interpolators %295
OpStore %174 %173
%176 = OpIAdd %int %295 %int_1
OpBranch %153
%155 = OpLabel
OpEmitVertex
OpEndPrimitive
OpBranch %73
%177 = OpLabel
%180 = OpAccessChain %_ptr_Output_v4float %_ %int_0
OpStore %180 %51
%181 = OpAccessChain %_ptr_Input_float %gl_in %int_0 %int_1
%182 = OpLoad %float %181
%183 = OpAccessChain %_ptr_Output_float %_ %int_1
OpStore %183 %182
%184 = OpAccessChain %_ptr_Input__arr_v4float_uint_16 %in_interpolators %int_0
%185 = OpLoad %_arr_v4float_uint_16 %184
OpStore %out_interpolators %185
OpEmitVertex
%186 = OpAccessChain %_ptr_Input_v4float %gl_in %int_1 %int_0
%187 = OpLoad %v4float %186
OpStore %180 %187
%189 = OpAccessChain %_ptr_Input_float %gl_in %int_1 %int_1
%190 = OpLoad %float %189
OpStore %183 %190
%192 = OpAccessChain %_ptr_Input__arr_v4float_uint_16 %in_interpolators %int_1
%193 = OpLoad %_arr_v4float_uint_16 %192
OpStore %out_interpolators %193
OpEmitVertex
%194 = OpAccessChain %_ptr_Input_v4float %gl_in %int_2 %int_0
%195 = OpLoad %v4float %194
OpStore %180 %195
%197 = OpAccessChain %_ptr_Input_float %gl_in %int_2 %int_1
%198 = OpLoad %float %197
OpStore %183 %198
%200 = OpAccessChain %_ptr_Input__arr_v4float_uint_16 %in_interpolators %int_2
%201 = OpLoad %_arr_v4float_uint_16 %200
OpStore %out_interpolators %201
OpEmitVertex
OpEndPrimitive
OpStore %180 %51
OpStore %183 %182
OpStore %out_interpolators %185
OpEmitVertex
OpStore %180 %195
OpStore %183 %198
OpStore %out_interpolators %201
OpEmitVertex
%223 = OpVectorShuffle %v2float %187 %187 0 1
%224 = OpFNegate %v2float %223
%225 = OpFAdd %v2float %52 %224
%228 = OpVectorShuffle %v2float %195 %195 0 1
%229 = OpFAdd %v2float %225 %228
%233 = OpCompositeExtract %float %229 0
%234 = OpCompositeExtract %float %229 1
%235 = OpCompositeExtract %float %195 2
%236 = OpCompositeExtract %float %195 3
%237 = OpCompositeConstruct %v4float %233 %234 %235 %236
OpStore %180 %237
OpStore %183 %198
OpBranch %243
%243 = OpLabel
%294 = OpPhi %int %int_0 %177 %265 %244
%249 = OpSLessThan %bool %294 %int_16
OpLoopMerge %245 %244 None
OpBranchConditional %249 %244 %245
%244 = OpLabel
%252 = OpAccessChain %_ptr_Input_v4float %in_interpolators %int_0 %294
%253 = OpLoad %v4float %252
%255 = OpAccessChain %_ptr_Input_v4float %in_interpolators %int_1 %294
%256 = OpLoad %v4float %255
%257 = OpFNegate %v4float %256
%258 = OpFAdd %v4float %253 %257
%260 = OpAccessChain %_ptr_Input_v4float %in_interpolators %int_2 %294
%261 = OpLoad %v4float %260
%262 = OpFAdd %v4float %258 %261
%263 = OpAccessChain %_ptr_Output_v4float %out_interpolators %294
OpStore %263 %262
%265 = OpIAdd %int %294 %int_1
OpBranch %243
%245 = OpLabel
OpEmitVertex
OpEndPrimitive
OpBranch %73
%73 = OpLabel
OpReturn
OpFunctionEnd

View File

@@ -1,35 +0,0 @@
// NOTE: This file is compiled and embedded into the exe.
// Use `xenia-build genspirv` and check in any changes under bin/.
#version 450 core
#extension all : warn
#extension GL_ARB_shading_language_420pack : require
#extension GL_ARB_separate_shader_objects : require
#extension GL_ARB_explicit_attrib_location : require
layout(set = 0, binding = 1) uniform consts_type {
vec4 float_consts[512];
uint loop_consts[32];
uint bool_consts[8];
} consts;
layout(push_constant) uniform push_consts_type {
vec4 window_scale;
vec4 vtx_fmt;
vec4 point_size;
vec4 alpha_test;
uint ps_param_gen;
} push_constants;
layout(set = 1, binding = 0) uniform sampler1D textures1D[32];
layout(set = 1, binding = 1) uniform sampler2D textures2D[32];
layout(set = 1, binding = 2) uniform sampler3D textures3D[32];
layout(set = 1, binding = 3) uniform samplerCube textures4D[32];
layout(location = 0) in vec4 in_interpolators[16];
layout(location = 0) out vec4 oC[4];
void main() {
// This shader does absolutely nothing!
return;
}

View File

@@ -1,53 +0,0 @@
// NOTE: This file is compiled and embedded into the exe.
// Use `xenia-build genspirv` and check in any changes under bin/.
#version 450 core
#extension all : warn
#extension GL_ARB_separate_shader_objects : require
#extension GL_ARB_explicit_attrib_location : require
in gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
// float gl_ClipDistance[];
} gl_in[];
out gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
// float gl_ClipDistance[];
};
layout(location = 0) in vec4 in_interpolators[][16];
layout(location = 0) out vec4 out_interpolators[16];
layout(location = 16) in vec2 _in_point_coord_unused[];
layout(location = 17) in float _in_point_size_unused[];
layout(location = 16) out vec2 _out_point_coord_unused;
layout(lines_adjacency) in;
layout(line_strip, max_vertices = 5) out;
void main() {
gl_Position = gl_in[0].gl_Position;
gl_PointSize = gl_in[0].gl_PointSize;
out_interpolators = in_interpolators[0];
EmitVertex();
gl_Position = gl_in[1].gl_Position;
gl_PointSize = gl_in[1].gl_PointSize;
out_interpolators = in_interpolators[1];
EmitVertex();
gl_Position = gl_in[2].gl_Position;
gl_PointSize = gl_in[2].gl_PointSize;
out_interpolators = in_interpolators[2];
EmitVertex();
gl_Position = gl_in[3].gl_Position;
gl_PointSize = gl_in[3].gl_PointSize;
out_interpolators = in_interpolators[3];
EmitVertex();
gl_Position = gl_in[0].gl_Position;
gl_PointSize = gl_in[0].gl_PointSize;
out_interpolators = in_interpolators[0];
EmitVertex();
EndPrimitive();
}

View File

@@ -1,63 +0,0 @@
// NOTE: This file is compiled and embedded into the exe.
// Use `xenia-build genspirv` and check in any changes under bin/.
#version 450 core
#extension all : warn
#extension GL_ARB_shading_language_420pack : require
#extension GL_ARB_separate_shader_objects : require
#extension GL_ARB_explicit_attrib_location : require
layout(push_constant) uniform push_consts_type {
vec4 window_scale;
vec4 vtx_fmt;
vec4 point_size;
vec4 alpha_test;
uint ps_param_gen;
} push_constants;
in gl_PerVertex {
vec4 gl_Position;
// float gl_ClipDistance[];
} gl_in[];
out gl_PerVertex {
vec4 gl_Position;
// float gl_ClipDistance[];
};
layout(location = 0) in vec4 in_interpolators[][16];
layout(location = 16) in vec2 in_point_coord_unused[];
layout(location = 17) in float point_size[];
layout(location = 0) out vec4 out_interpolators[16];
layout(location = 16) out vec2 point_coord;
// TODO(benvanik): clamp to min/max.
// TODO(benvanik): figure out how to see which interpolator gets adjusted.
layout(points) in;
layout(triangle_strip, max_vertices = 4) out;
void main() {
const vec2 offsets[4] = {
vec2(-1.0, 1.0),
vec2( 1.0, 1.0),
vec2(-1.0, -1.0),
vec2( 1.0, -1.0),
};
vec4 pos = gl_in[0].gl_Position;
vec2 window_scaled_psize = push_constants.point_size.xy;
// Shader header writes -1.0f to pointSize by default, so any positive value
// means that it was overwritten by the translated vertex shader.
if (point_size[0] > 0.0f) {
window_scaled_psize = vec2(point_size[0]);
}
window_scaled_psize /= push_constants.window_scale.zw;
for (int i = 0; i < 4; ++i) {
gl_Position = vec4(pos.xy + (offsets[i] * window_scaled_psize), pos.zw);
out_interpolators = in_interpolators[0];
point_coord = max(offsets[i], vec2(0.0f));
EmitVertex();
}
EndPrimitive();
}

View File

@@ -1,42 +0,0 @@
// NOTE: This file is compiled and embedded into the exe.
// Use `xenia-build genspirv` and check in any changes under bin/.
#version 450 core
#extension all : warn
#extension GL_ARB_shading_language_420pack : require
#extension GL_ARB_separate_shader_objects : require
#extension GL_ARB_explicit_attrib_location : require
in gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
// float gl_ClipDistance[];
} gl_in[];
out gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
// float gl_ClipDistance[];
};
layout(location = 0) in vec4 in_interpolators[][16];
layout(location = 0) out vec4 out_interpolators[16];
layout(location = 16) in vec2 _in_point_coord_unused[];
layout(location = 17) in float _in_point_size_unused[];
layout(location = 16) out vec2 _out_point_coord_unused;
layout(lines_adjacency) in;
layout(triangle_strip, max_vertices = 4) out;
void main() {
const int order[4] = { 0, 1, 3, 2 };
for (int i = 0; i < 4; ++i) {
int input_index = order[i];
gl_Position = gl_in[input_index].gl_Position;
gl_PointSize = gl_in[input_index].gl_PointSize;
out_interpolators = in_interpolators[input_index];
EmitVertex();
}
EndPrimitive();
}

View File

@@ -1,124 +0,0 @@
// NOTE: This file is compiled and embedded into the exe.
// Use `xenia-build genspirv` and check in any changes under bin/.
#version 450 core
#extension all : warn
#extension GL_ARB_separate_shader_objects : require
#extension GL_ARB_explicit_attrib_location : require
in gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
// float gl_ClipDistance[];
} gl_in[];
out gl_PerVertex {
vec4 gl_Position;
float gl_PointSize;
// float gl_ClipDistance[];
};
layout(location = 0) in vec4 in_interpolators[][16];
layout(location = 0) out vec4 out_interpolators[16];
layout(location = 16) in vec2 _in_point_coord_unused[];
layout(location = 17) in float _in_point_size_unused[];
layout(location = 16) out vec2 _out_point_coord_unused;
layout(triangles) in;
layout(triangle_strip, max_vertices = 6) out;
bool equalsEpsilon(vec2 left, vec2 right, float epsilon) {
return all(lessThanEqual(abs(left - right), vec2(epsilon)));
}
void main() {
// Most games use a left-aligned form.
if (equalsEpsilon(gl_in[0].gl_Position.xy, vec2(gl_in[2].gl_Position.x, gl_in[1].gl_Position.y), 0.001) ||
equalsEpsilon(gl_in[0].gl_Position.xy, vec2(gl_in[1].gl_Position.x, gl_in[2].gl_Position.y), 0.001)) {
// 0 ------ 1 0: -1,-1
// | - | 1: 1,-1
// | // | 2: -1, 1
// | - | 3: [ 1, 1 ]
// 2 ----- [3]
//
// 0 ------ 2 0: -1,-1
// | - | 1: -1, 1
// | // | 2: 1,-1
// | - | 3: [ 1, 1 ]
// 1 ------[3]
gl_Position = gl_in[0].gl_Position;
gl_PointSize = gl_in[0].gl_PointSize;
out_interpolators = in_interpolators[0];
EmitVertex();
gl_Position = gl_in[1].gl_Position;
gl_PointSize = gl_in[1].gl_PointSize;
out_interpolators = in_interpolators[1];
EmitVertex();
gl_Position = gl_in[2].gl_Position;
gl_PointSize = gl_in[2].gl_PointSize;
out_interpolators = in_interpolators[2];
EmitVertex();
EndPrimitive();
gl_Position = gl_in[2].gl_Position;
gl_PointSize = gl_in[2].gl_PointSize;
out_interpolators = in_interpolators[2];
EmitVertex();
gl_Position = gl_in[1].gl_Position;
gl_PointSize = gl_in[1].gl_PointSize;
out_interpolators = in_interpolators[1];
EmitVertex();
gl_Position = vec4((-gl_in[0].gl_Position.xy) +
gl_in[1].gl_Position.xy +
gl_in[2].gl_Position.xy,
gl_in[2].gl_Position.zw);
gl_PointSize = gl_in[2].gl_PointSize;
for (int i = 0; i < 16; ++i) {
out_interpolators[i] = (-in_interpolators[0][i]) +
in_interpolators[1][i] +
in_interpolators[2][i];
}
EmitVertex();
EndPrimitive();
} else {
// 0 ------ 1 0: -1,-1
// | - | 1: 1,-1
// | \\ | 2: 1, 1
// | - | 3: [-1, 1 ]
// [3] ----- 2
gl_Position = gl_in[0].gl_Position;
gl_PointSize = gl_in[0].gl_PointSize;
out_interpolators = in_interpolators[0];
EmitVertex();
gl_Position = gl_in[1].gl_Position;
gl_PointSize = gl_in[1].gl_PointSize;
out_interpolators = in_interpolators[1];
EmitVertex();
gl_Position = gl_in[2].gl_Position;
gl_PointSize = gl_in[2].gl_PointSize;
out_interpolators = in_interpolators[2];
EmitVertex();
EndPrimitive();
gl_Position = gl_in[0].gl_Position;
gl_PointSize = gl_in[0].gl_PointSize;
out_interpolators = in_interpolators[0];
EmitVertex();
gl_Position = gl_in[2].gl_Position;
gl_PointSize = gl_in[2].gl_PointSize;
out_interpolators = in_interpolators[2];
EmitVertex();
gl_Position = vec4( gl_in[0].gl_Position.xy +
(-gl_in[1].gl_Position.xy) +
gl_in[2].gl_Position.xy,
gl_in[2].gl_Position.zw);
gl_PointSize = gl_in[2].gl_PointSize;
for (int i = 0; i < 16; ++i) {
out_interpolators[i] = in_interpolators[0][i] +
(-in_interpolators[1][i]) +
in_interpolators[2][i];
}
EmitVertex();
EndPrimitive();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,244 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_GPU_VULKAN_TEXTURE_CACHE_H_
#define XENIA_GPU_VULKAN_TEXTURE_CACHE_H_
#include <algorithm>
#include <list>
#include <unordered_map>
#include <unordered_set>
#include "xenia/base/mutex.h"
#include "xenia/gpu/register_file.h"
#include "xenia/gpu/sampler_info.h"
#include "xenia/gpu/shader.h"
#include "xenia/gpu/texture_conversion.h"
#include "xenia/gpu/texture_info.h"
#include "xenia/gpu/trace_writer.h"
#include "xenia/gpu/vulkan/vulkan_command_processor.h"
#include "xenia/gpu/xenos.h"
#include "xenia/ui/vulkan/circular_buffer.h"
#include "xenia/ui/vulkan/fenced_pools.h"
#include "xenia/ui/vulkan/vulkan.h"
#include "xenia/ui/vulkan/vulkan_device.h"
#include "third_party/vulkan/vk_mem_alloc.h"
namespace xe {
namespace gpu {
namespace vulkan {
//
class TextureCache {
public:
struct TextureView;
// This represents an uploaded Vulkan texture.
struct Texture {
TextureInfo texture_info;
std::vector<std::unique_ptr<TextureView>> views;
VkFormat format;
VkImage image;
VkImageLayout image_layout;
VmaAllocation alloc;
VmaAllocationInfo alloc_info;
VkFramebuffer framebuffer; // Blit target frame buffer.
VkImageUsageFlags usage_flags;
bool is_watched;
bool pending_invalidation;
// Pointer to the latest usage fence.
VkFence in_flight_fence;
};
struct TextureView {
Texture* texture;
VkImageView view;
union {
struct {
// FIXME: This only applies on little-endian platforms!
uint16_t swiz_x : 3;
uint16_t swiz_y : 3;
uint16_t swiz_z : 3;
uint16_t swiz_w : 3;
uint16_t : 4;
};
uint16_t swizzle;
};
};
TextureCache(Memory* memory, RegisterFile* register_file,
TraceWriter* trace_writer, ui::vulkan::VulkanDevice* device);
~TextureCache();
VkResult Initialize();
void Shutdown();
// Descriptor set layout containing all possible texture bindings.
// The set contains one descriptor for each texture sampler [0-31].
VkDescriptorSetLayout texture_descriptor_set_layout() const {
return texture_descriptor_set_layout_;
}
// Prepares a descriptor set containing the samplers and images for all
// bindings. The textures will be uploaded/converted/etc as needed.
// Requires a fence to be provided that will be signaled when finished
// using the returned descriptor set.
VkDescriptorSet PrepareTextureSet(
VkCommandBuffer setup_command_buffer, VkFence completion_fence,
const std::vector<Shader::TextureBinding>& vertex_bindings,
const std::vector<Shader::TextureBinding>& pixel_bindings);
// TODO(benvanik): ReadTexture.
Texture* Lookup(const TextureInfo& texture_info);
// Looks for a texture either containing or matching these parameters.
// Caller is responsible for checking if the texture returned is an exact
// match or just contains the texture given by the parameters.
// If offset_x and offset_y are not null, this may return a texture that
// contains this address at an offset.
Texture* LookupAddress(uint32_t guest_address, uint32_t width,
uint32_t height, xenos::TextureFormat format,
VkOffset2D* out_offset = nullptr);
TextureView* DemandView(Texture* texture, uint16_t swizzle);
// Demands a texture for the purpose of resolving from EDRAM. This either
// creates a new texture or returns a previously created texture.
Texture* DemandResolveTexture(const TextureInfo& texture_info);
// Clears all cached content.
void ClearCache();
// Frees any unused resources
void Scavenge();
private:
struct UpdateSetInfo;
// Cached Vulkan sampler.
struct Sampler {
SamplerInfo sampler_info;
VkSampler sampler;
};
struct WatchedTexture {
Texture* texture;
bool is_mip;
};
// Allocates a new texture and memory to back it on the GPU.
Texture* AllocateTexture(const TextureInfo& texture_info,
VkFormatFeatureFlags required_flags =
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT);
bool FreeTexture(Texture* texture);
void WatchTexture(Texture* texture);
void TextureTouched(Texture* texture);
std::pair<uint32_t, uint32_t> MemoryInvalidationCallback(
uint32_t physical_address_start, uint32_t length, bool exact_range);
static std::pair<uint32_t, uint32_t> MemoryInvalidationCallbackThunk(
void* context_ptr, uint32_t physical_address_start, uint32_t length,
bool exact_range);
// Demands a texture. If command_buffer is null and the texture hasn't been
// uploaded to graphics memory already, we will return null and bail.
Texture* Demand(const TextureInfo& texture_info,
VkCommandBuffer command_buffer = nullptr,
VkFence completion_fence = nullptr);
Sampler* Demand(const SamplerInfo& sampler_info);
void FlushPendingCommands(VkCommandBuffer command_buffer,
VkFence completion_fence);
bool ConvertTexture(uint8_t* dest, VkBufferImageCopy* copy_region,
uint32_t mip, const TextureInfo& src);
static const FormatInfo* GetFormatInfo(xenos::TextureFormat format);
static texture_conversion::CopyBlockCallback GetFormatCopyBlock(
xenos::TextureFormat format);
static TextureExtent GetMipExtent(const TextureInfo& src, uint32_t mip);
static uint32_t ComputeMipStorage(const FormatInfo* format_info,
uint32_t width, uint32_t height,
uint32_t depth, uint32_t mip);
static uint32_t ComputeMipStorage(const TextureInfo& src, uint32_t mip);
static uint32_t ComputeTextureStorage(const TextureInfo& src);
// Writes a texture back into guest memory. This call is (mostly) asynchronous
// but the texture must not be flagged for destruction.
void WritebackTexture(Texture* texture);
// Queues commands to upload a texture from system memory, applying any
// conversions necessary. This may flush the command buffer to the GPU if we
// run out of staging memory.
bool UploadTexture(VkCommandBuffer command_buffer, VkFence completion_fence,
Texture* dest, const TextureInfo& src);
void HashTextureBindings(XXH64_state_t* hash_state, uint32_t& fetch_mask,
const std::vector<Shader::TextureBinding>& bindings);
bool SetupTextureBindings(
VkCommandBuffer command_buffer, VkFence completion_fence,
UpdateSetInfo* update_set_info,
const std::vector<Shader::TextureBinding>& bindings);
bool SetupTextureBinding(VkCommandBuffer command_buffer,
VkFence completion_fence,
UpdateSetInfo* update_set_info,
const Shader::TextureBinding& binding);
// Removes invalidated textures from the cache, queues them for delete.
void RemoveInvalidatedTextures();
Memory* memory_ = nullptr;
RegisterFile* register_file_ = nullptr;
TraceWriter* trace_writer_ = nullptr;
ui::vulkan::VulkanDevice* device_ = nullptr;
VkQueue device_queue_ = nullptr;
std::unique_ptr<xe::ui::vulkan::CommandBufferPool> wb_command_pool_ = nullptr;
std::unique_ptr<xe::ui::vulkan::DescriptorPool> descriptor_pool_ = nullptr;
std::unordered_map<uint64_t, VkDescriptorSet> texture_sets_;
VkDescriptorSetLayout texture_descriptor_set_layout_ = nullptr;
VmaAllocator mem_allocator_ = nullptr;
ui::vulkan::CircularBuffer staging_buffer_;
ui::vulkan::CircularBuffer wb_staging_buffer_;
std::unordered_map<uint64_t, Texture*> textures_;
std::unordered_map<uint64_t, Sampler*> samplers_;
std::list<Texture*> pending_delete_textures_;
void* memory_invalidation_callback_handle_ = nullptr;
xe::global_critical_region global_critical_region_;
std::list<WatchedTexture> watched_textures_;
std::unordered_set<Texture*>* invalidated_textures_;
std::unordered_set<Texture*> invalidated_textures_sets_[2];
struct UpdateSetInfo {
// Bitmap of all 32 fetch constants and whether they have been setup yet.
// This prevents duplication across the vertex and pixel shader.
uint32_t has_setup_fetch_mask;
uint32_t image_write_count = 0;
VkWriteDescriptorSet image_writes[32];
VkDescriptorImageInfo image_infos[32];
} update_set_info_;
};
} // namespace vulkan
} // namespace gpu
} // namespace xe
#endif // XENIA_GPU_VULKAN_TEXTURE_CACHE_H_

View File

@@ -1,146 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/gpu/vulkan/texture_config.h"
namespace xe {
namespace gpu {
namespace vulkan {
#define COMP_SWIZ(r, g, b, a) \
{ \
VK_COMPONENT_SWIZZLE_##r, VK_COMPONENT_SWIZZLE_##g, \
VK_COMPONENT_SWIZZLE_##b, VK_COMPONENT_SWIZZLE_##a \
}
#define VEC_SWIZ(x, y, z, w) \
{ \
VECTOR_SWIZZLE_##x, VECTOR_SWIZZLE_##y, VECTOR_SWIZZLE_##z, \
VECTOR_SWIZZLE_##w \
}
#define RGBA COMP_SWIZ(R, G, B, A)
#define ___R COMP_SWIZ(IDENTITY, IDENTITY, IDENTITY, R)
#define RRRR COMP_SWIZ(R, R, R, R)
#define XYZW VEC_SWIZ(X, Y, Z, W)
#define YXWZ VEC_SWIZ(Y, X, W, Z)
#define ZYXW VEC_SWIZ(Z, Y, X, W)
#define ___(format) \
{ VK_FORMAT_##format }
#define _c_(format, component_swizzle) \
{ VK_FORMAT_##format, component_swizzle, XYZW }
#define __v(format, vector_swizzle) \
{ VK_FORMAT_##format, RGBA, vector_swizzle }
#define _cv(format, component_swizzle, vector_swizzle) \
{ VK_FORMAT_##format, component_swizzle, vector_swizzle }
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/VkFormat.html
const TextureConfig texture_configs[64] = {
/* k_1_REVERSE */ ___(UNDEFINED),
/* k_1 */ ___(UNDEFINED),
/* k_8 */ ___(R8_UNORM),
/* k_1_5_5_5 */ __v(A1R5G5B5_UNORM_PACK16, ZYXW),
/* k_5_6_5 */ __v(R5G6B5_UNORM_PACK16, ZYXW),
/* k_6_5_5 */ ___(UNDEFINED),
/* k_8_8_8_8 */ ___(R8G8B8A8_UNORM),
/* k_2_10_10_10 */ ___(A2R10G10B10_UNORM_PACK32),
/* k_8_A */ ___(R8_UNORM),
/* k_8_B */ ___(UNDEFINED),
/* k_8_8 */ ___(R8G8_UNORM),
/* k_Cr_Y1_Cb_Y0_REP */ ___(UNDEFINED),
/* k_Y1_Cr_Y0_Cb_REP */ ___(UNDEFINED),
/* k_16_16_EDRAM */ ___(UNDEFINED),
/* k_8_8_8_8_A */ ___(UNDEFINED),
/* k_4_4_4_4 */ __v(R4G4B4A4_UNORM_PACK16, YXWZ),
// TODO: Verify if these two are correct (I think not).
/* k_10_11_11 */ ___(B10G11R11_UFLOAT_PACK32),
/* k_11_11_10 */ ___(B10G11R11_UFLOAT_PACK32),
/* k_DXT1 */ ___(BC1_RGBA_UNORM_BLOCK),
/* k_DXT2_3 */ ___(BC2_UNORM_BLOCK),
/* k_DXT4_5 */ ___(BC3_UNORM_BLOCK),
/* k_16_16_16_16_EDRAM */ ___(UNDEFINED),
// TODO: D24 unsupported on AMD.
/* k_24_8 */ ___(D24_UNORM_S8_UINT),
/* k_24_8_FLOAT */ ___(D32_SFLOAT_S8_UINT),
/* k_16 */ ___(R16_UNORM),
/* k_16_16 */ ___(R16G16_UNORM),
/* k_16_16_16_16 */ ___(R16G16B16A16_UNORM),
/* k_16_EXPAND */ ___(R16_SFLOAT),
/* k_16_16_EXPAND */ ___(R16G16_SFLOAT),
/* k_16_16_16_16_EXPAND */ ___(R16G16B16A16_SFLOAT),
/* k_16_FLOAT */ ___(R16_SFLOAT),
/* k_16_16_FLOAT */ ___(R16G16_SFLOAT),
/* k_16_16_16_16_FLOAT */ ___(R16G16B16A16_SFLOAT),
// ! These are UNORM formats, not SINT.
/* k_32 */ ___(R32_SINT),
/* k_32_32 */ ___(R32G32_SINT),
/* k_32_32_32_32 */ ___(R32G32B32A32_SINT),
/* k_32_FLOAT */ ___(R32_SFLOAT),
/* k_32_32_FLOAT */ ___(R32G32_SFLOAT),
/* k_32_32_32_32_FLOAT */ ___(R32G32B32A32_SFLOAT),
/* k_32_AS_8 */ ___(UNDEFINED),
/* k_32_AS_8_8 */ ___(UNDEFINED),
/* k_16_MPEG */ ___(UNDEFINED),
/* k_16_16_MPEG */ ___(UNDEFINED),
/* k_8_INTERLACED */ ___(UNDEFINED),
/* k_32_AS_8_INTERLACED */ ___(UNDEFINED),
/* k_32_AS_8_8_INTERLACED */ ___(UNDEFINED),
/* k_16_INTERLACED */ ___(UNDEFINED),
/* k_16_MPEG_INTERLACED */ ___(UNDEFINED),
/* k_16_16_MPEG_INTERLACED */ ___(UNDEFINED),
// https://fileadmin.cs.lth.se/cs/Personal/Michael_Doggett/talks/unc-xenos-doggett.pdf
/* k_DXN */ ___(BC5_UNORM_BLOCK), // ?
/* k_8_8_8_8_AS_16_16_16_16 */ ___(R8G8B8A8_UNORM),
/* k_DXT1_AS_16_16_16_16 */ ___(BC1_RGBA_UNORM_BLOCK),
/* k_DXT2_3_AS_16_16_16_16 */ ___(BC2_UNORM_BLOCK),
/* k_DXT4_5_AS_16_16_16_16 */ ___(BC3_UNORM_BLOCK),
/* k_2_10_10_10_AS_16_16_16_16 */ ___(A2R10G10B10_UNORM_PACK32),
// TODO: Verify if these two are correct (I think not).
/* k_10_11_11_AS_16_16_16_16 */ ___(B10G11R11_UFLOAT_PACK32), // ?
/* k_11_11_10_AS_16_16_16_16 */ ___(B10G11R11_UFLOAT_PACK32), // ?
/* k_32_32_32_FLOAT */ ___(R32G32B32_SFLOAT),
/* k_DXT3A */ _c_(BC2_UNORM_BLOCK, ___R),
/* k_DXT5A */ _c_(BC4_UNORM_BLOCK, RRRR), // ATI1N
// https://fileadmin.cs.lth.se/cs/Personal/Michael_Doggett/talks/unc-xenos-doggett.pdf
/* k_CTX1 */ ___(R8G8_UINT),
/* k_DXT3A_AS_1_1_1_1 */ ___(UNDEFINED),
/* k_8_8_8_8_GAMMA_EDRAM */ ___(UNDEFINED),
/* k_2_10_10_10_FLOAT_EDRAM */ ___(UNDEFINED),
};
#undef _cv
#undef __v
#undef _c_
#undef ___
#undef ZYXW
#undef YXWZ
#undef XYZW
#undef RRRR
#undef ___R
#undef RGBA
#undef VEC_SWIZ
#undef COMP_SWIZ
} // namespace vulkan
} // namespace gpu
} // namespace xe

View File

@@ -1,50 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_GPU_VULKAN_TEXTURE_CONFIG_H_
#define XENIA_GPU_VULKAN_TEXTURE_CONFIG_H_
#include "third_party/volk/volk.h"
#include "xenia/gpu/texture_info.h"
#include "xenia/gpu/xenos.h"
namespace xe {
namespace gpu {
namespace vulkan {
typedef enum VectorSwizzle {
VECTOR_SWIZZLE_X = 0,
VECTOR_SWIZZLE_Y = 1,
VECTOR_SWIZZLE_Z = 2,
VECTOR_SWIZZLE_W = 3,
} VectorSwizzle;
struct TextureConfig {
VkFormat host_format;
struct {
VkComponentSwizzle r = VK_COMPONENT_SWIZZLE_R;
VkComponentSwizzle g = VK_COMPONENT_SWIZZLE_G;
VkComponentSwizzle b = VK_COMPONENT_SWIZZLE_B;
VkComponentSwizzle a = VK_COMPONENT_SWIZZLE_A;
} component_swizzle;
struct {
VectorSwizzle x = VECTOR_SWIZZLE_X;
VectorSwizzle y = VECTOR_SWIZZLE_Y;
VectorSwizzle z = VECTOR_SWIZZLE_Z;
VectorSwizzle w = VECTOR_SWIZZLE_W;
} vector_swizzle;
};
extern const TextureConfig texture_configs[64];
} // namespace vulkan
} // namespace gpu
} // namespace xe
#endif // XENIA_GPU_VULKAN_TEXTURE_CONFIG_H_

File diff suppressed because it is too large Load Diff

View File

@@ -10,69 +10,29 @@
#ifndef XENIA_GPU_VULKAN_VULKAN_COMMAND_PROCESSOR_H_
#define XENIA_GPU_VULKAN_VULKAN_COMMAND_PROCESSOR_H_
#include <atomic>
#include <cstring>
#include <functional>
#include <memory>
#include <mutex>
#include <queue>
#include <string>
#include <unordered_map>
#include <vector>
#include "xenia/base/threading.h"
#include "xenia/gpu/command_processor.h"
#include "xenia/gpu/register_file.h"
#include "xenia/gpu/vulkan/buffer_cache.h"
#include "xenia/gpu/vulkan/pipeline_cache.h"
#include "xenia/gpu/vulkan/render_cache.h"
#include "xenia/gpu/vulkan/texture_cache.h"
#include "xenia/gpu/vulkan/vulkan_shader.h"
#include "xenia/gpu/vulkan/vulkan_graphics_system.h"
#include "xenia/gpu/xenos.h"
#include "xenia/kernel/xthread.h"
#include "xenia/memory.h"
#include "xenia/ui/vulkan/blitter.h"
#include "xenia/ui/vulkan/fenced_pools.h"
#include "xenia/ui/vulkan/vulkan_context.h"
#include "xenia/ui/vulkan/vulkan_device.h"
#include "xenia/ui/vulkan/vulkan_util.h"
#include "xenia/kernel/kernel_state.h"
namespace xe {
namespace gpu {
namespace vulkan {
class VulkanGraphicsSystem;
class TextureCache;
class VulkanCommandProcessor : public CommandProcessor {
public:
VulkanCommandProcessor(VulkanGraphicsSystem* graphics_system,
kernel::KernelState* kernel_state);
~VulkanCommandProcessor() override;
~VulkanCommandProcessor();
void RequestFrameTrace(const std::filesystem::path& root_path) override;
void TracePlaybackWroteMemory(uint32_t base_ptr, uint32_t length) override;
void RestoreEdramSnapshot(const void* snapshot) override;
void ClearCaches() override;
RenderCache* render_cache() { return render_cache_.get(); }
void RestoreEdramSnapshot(const void* snapshot) override;
private:
bool SetupContext() override;
void ShutdownContext() override;
void MakeCoherent() override;
void PrepareForWait() override;
void ReturnFromWait() override;
void WriteRegister(uint32_t index, uint32_t value) override;
void BeginFrame();
void EndFrame();
void CreateSwapImage(VkCommandBuffer setup_buffer, VkExtent2D extents);
void DestroySwapImage();
void PerformSwap(uint32_t frontbuffer_ptr, uint32_t frontbuffer_width,
uint32_t frontbuffer_height) override;
@@ -80,69 +40,13 @@ class VulkanCommandProcessor : public CommandProcessor {
const uint32_t* host_address,
uint32_t dword_count) override;
bool IssueDraw(xenos::PrimitiveType primitive_type, uint32_t index_count,
bool IssueDraw(xenos::PrimitiveType prim_type, uint32_t index_count,
IndexBufferInfo* index_buffer_info,
bool major_mode_explicit) override;
bool PopulateConstants(VkCommandBuffer command_buffer,
VulkanShader* vertex_shader,
VulkanShader* pixel_shader);
bool PopulateIndexBuffer(VkCommandBuffer command_buffer,
IndexBufferInfo* index_buffer_info);
bool PopulateVertexBuffers(VkCommandBuffer command_buffer,
VkCommandBuffer setup_buffer,
VulkanShader* vertex_shader);
bool PopulateSamplers(VkCommandBuffer command_buffer,
VkCommandBuffer setup_buffer,
VulkanShader* vertex_shader,
VulkanShader* pixel_shader);
bool IssueCopy() override;
void InitializeTrace() override;
void FinalizeTrace() override;
xe::ui::vulkan::VulkanDevice* device_ = nullptr;
// front buffer / back buffer memory
VkDeviceMemory fb_memory_ = nullptr;
VkImageView fb_image_view_ = nullptr;
VkFramebuffer fb_framebuffer_ = nullptr;
uint64_t dirty_float_constants_ = 0; // Dirty float constants in blocks of 4
uint8_t dirty_bool_constants_ = 0;
uint32_t dirty_loop_constants_ = 0;
uint8_t dirty_gamma_constants_ = 0;
uint32_t coher_base_vc_ = 0;
uint32_t coher_size_vc_ = 0;
// TODO(benvanik): abstract behind context?
// Queue used to submit work. This may be a dedicated queue for the command
// processor and no locking will be required for use. If a dedicated queue
// was not available this will be the device primary_queue and the
// queue_mutex must be used to synchronize access to it.
VkQueue queue_ = nullptr;
std::mutex* queue_mutex_ = nullptr;
// Last copy base address, for debugging only.
uint32_t last_copy_base_ = 0;
bool capturing_ = false;
bool trace_requested_ = false;
bool cache_clear_requested_ = false;
std::unique_ptr<BufferCache> buffer_cache_;
std::unique_ptr<PipelineCache> pipeline_cache_;
std::unique_ptr<RenderCache> render_cache_;
std::unique_ptr<TextureCache> texture_cache_;
std::unique_ptr<ui::vulkan::Blitter> blitter_;
std::unique_ptr<ui::vulkan::CommandBufferPool> command_buffer_pool_;
bool frame_open_ = false;
const RenderState* current_render_state_ = nullptr;
VkCommandBuffer current_command_buffer_ = nullptr;
VkCommandBuffer current_setup_buffer_ = nullptr;
VkFence current_batch_fence_;
};
} // namespace vulkan

View File

@@ -1,16 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/gpu/vulkan/vulkan_gpu_flags.h"
DEFINE_bool(vulkan_renderdoc_capture_all, false,
"Capture everything with RenderDoc.", "Vulkan");
DEFINE_bool(vulkan_native_msaa, false, "Use native MSAA", "Vulkan");
DEFINE_bool(vulkan_dump_disasm, false,
"Dump shader disassembly. NVIDIA only supported.", "Vulkan");

View File

@@ -1,20 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_GPU_VULKAN_VULKAN_GPU_FLAGS_H_
#define XENIA_GPU_VULKAN_VULKAN_GPU_FLAGS_H_
#define FINE_GRAINED_DRAW_SCOPES 1
#include "xenia/base/cvar.h"
DECLARE_bool(vulkan_renderdoc_capture_all);
DECLARE_bool(vulkan_native_msaa);
DECLARE_bool(vulkan_dump_disasm);
#endif // XENIA_GPU_VULKAN_VULKAN_GPU_FLAGS_H_

View File

@@ -2,261 +2,39 @@
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Copyright 2020 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/gpu/vulkan/vulkan_graphics_system.h"
#include <algorithm>
#include <cstring>
#include "xenia/base/logging.h"
#include "xenia/base/profiling.h"
#include "xenia/cpu/processor.h"
#include "xenia/gpu/gpu_flags.h"
#include "xenia/gpu/vulkan/vulkan_command_processor.h"
#include "xenia/gpu/vulkan/vulkan_gpu_flags.h"
#include "xenia/ui/vulkan/vulkan_provider.h"
#include "xenia/ui/vulkan/vulkan_swap_chain.h"
#include "xenia/ui/vulkan/vulkan_util.h"
#include "xenia/ui/window.h"
#include "xenia/xbox.h"
namespace xe {
namespace gpu {
namespace vulkan {
using xe::ui::RawImage;
using xe::ui::vulkan::CheckResult;
VulkanGraphicsSystem::VulkanGraphicsSystem() {}
VulkanGraphicsSystem::~VulkanGraphicsSystem() = default;
VulkanGraphicsSystem::~VulkanGraphicsSystem() {}
X_STATUS VulkanGraphicsSystem::Setup(cpu::Processor* processor,
kernel::KernelState* kernel_state,
ui::Window* target_window) {
// Must create the provider so we can create contexts.
auto provider = xe::ui::vulkan::VulkanProvider::Create(target_window);
device_ = provider->device();
provider_ = std::move(provider);
provider_ = xe::ui::vulkan::VulkanProvider::Create(target_window);
auto result = GraphicsSystem::Setup(processor, kernel_state, target_window);
if (result) {
return result;
}
if (target_window) {
display_context_ = reinterpret_cast<xe::ui::vulkan::VulkanContext*>(
target_window->context());
}
// Create our own command pool we can use for captures.
VkCommandPoolCreateInfo create_info = {
VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
nullptr,
VK_COMMAND_POOL_CREATE_TRANSIENT_BIT |
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
device_->queue_family_index(),
};
auto status =
vkCreateCommandPool(*device_, &create_info, nullptr, &command_pool_);
CheckResult(status, "vkCreateCommandPool");
return X_STATUS_SUCCESS;
return GraphicsSystem::Setup(processor, kernel_state, target_window);
}
void VulkanGraphicsSystem::Shutdown() {
GraphicsSystem::Shutdown();
vkDestroyCommandPool(*device_, command_pool_, nullptr);
}
std::unique_ptr<RawImage> VulkanGraphicsSystem::Capture() {
auto& swap_state = command_processor_->swap_state();
std::lock_guard<std::mutex> lock(swap_state.mutex);
if (!swap_state.front_buffer_texture) {
return nullptr;
}
VkResult status = VK_SUCCESS;
VkCommandBufferAllocateInfo alloc_info = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
nullptr,
command_pool_,
VK_COMMAND_BUFFER_LEVEL_PRIMARY,
1,
};
VkCommandBuffer cmd = nullptr;
status = vkAllocateCommandBuffers(*device_, &alloc_info, &cmd);
CheckResult(status, "vkAllocateCommandBuffers");
if (status != VK_SUCCESS) {
return nullptr;
}
VkCommandBufferBeginInfo begin_info = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
nullptr,
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
nullptr,
};
vkBeginCommandBuffer(cmd, &begin_info);
auto front_buffer =
reinterpret_cast<VkImage>(swap_state.front_buffer_texture);
status = CreateCaptureBuffer(cmd, {swap_state.width, swap_state.height});
if (status != VK_SUCCESS) {
vkFreeCommandBuffers(*device_, command_pool_, 1, &cmd);
return nullptr;
}
VkImageMemoryBarrier barrier;
std::memset(&barrier, 0, sizeof(VkImageMemoryBarrier));
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = front_buffer;
barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0,
nullptr, 1, &barrier);
// Copy front buffer into capture image.
VkBufferImageCopy region = {
0, 0,
0, {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
{0, 0, 0}, {swap_state.width, swap_state.height, 1},
};
vkCmdCopyImageToBuffer(cmd, front_buffer, VK_IMAGE_LAYOUT_GENERAL,
capture_buffer_, 1, &region);
VkBufferMemoryBarrier memory_barrier = {
VK_STRUCTURE_TYPE_MEMORY_BARRIER,
nullptr,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_HOST_READ_BIT | VK_ACCESS_MEMORY_READ_BIT,
VK_QUEUE_FAMILY_IGNORED,
VK_QUEUE_FAMILY_IGNORED,
capture_buffer_,
0,
VK_WHOLE_SIZE,
};
vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 1,
&memory_barrier, 0, nullptr);
status = vkEndCommandBuffer(cmd);
// Submit commands and wait.
if (status == VK_SUCCESS) {
std::lock_guard<std::mutex>(device_->primary_queue_mutex());
VkSubmitInfo submit_info = {
VK_STRUCTURE_TYPE_SUBMIT_INFO,
nullptr,
0,
nullptr,
nullptr,
1,
&cmd,
0,
nullptr,
};
status = vkQueueSubmit(device_->primary_queue(), 1, &submit_info, nullptr);
CheckResult(status, "vkQueueSubmit");
if (status == VK_SUCCESS) {
status = vkQueueWaitIdle(device_->primary_queue());
CheckResult(status, "vkQueueWaitIdle");
}
}
vkFreeCommandBuffers(*device_, command_pool_, 1, &cmd);
void* data;
if (status == VK_SUCCESS) {
status = vkMapMemory(*device_, capture_buffer_memory_, 0, VK_WHOLE_SIZE, 0,
&data);
CheckResult(status, "vkMapMemory");
}
if (status == VK_SUCCESS) {
std::unique_ptr<RawImage> raw_image(new RawImage());
raw_image->width = swap_state.width;
raw_image->height = swap_state.height;
raw_image->stride = swap_state.width * 4;
raw_image->data.resize(raw_image->stride * raw_image->height);
std::memcpy(raw_image->data.data(), data,
raw_image->stride * raw_image->height);
vkUnmapMemory(*device_, capture_buffer_memory_);
DestroyCaptureBuffer();
return raw_image;
}
DestroyCaptureBuffer();
return nullptr;
}
VkResult VulkanGraphicsSystem::CreateCaptureBuffer(VkCommandBuffer cmd,
VkExtent2D extents) {
VkResult status = VK_SUCCESS;
VkBufferCreateInfo buffer_info = {
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
nullptr,
0,
extents.width * extents.height * 4,
VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
VK_SHARING_MODE_EXCLUSIVE,
0,
nullptr,
};
status = vkCreateBuffer(*device_, &buffer_info, nullptr, &capture_buffer_);
if (status != VK_SUCCESS) {
return status;
}
capture_buffer_size_ = extents.width * extents.height * 4;
// Bind memory to buffer.
VkMemoryRequirements mem_requirements;
vkGetBufferMemoryRequirements(*device_, capture_buffer_, &mem_requirements);
capture_buffer_memory_ = device_->AllocateMemory(
mem_requirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
assert_not_null(capture_buffer_memory_);
status =
vkBindBufferMemory(*device_, capture_buffer_, capture_buffer_memory_, 0);
CheckResult(status, "vkBindImageMemory");
if (status != VK_SUCCESS) {
vkDestroyBuffer(*device_, capture_buffer_, nullptr);
return status;
}
return status;
}
void VulkanGraphicsSystem::DestroyCaptureBuffer() {
vkDestroyBuffer(*device_, capture_buffer_, nullptr);
vkFreeMemory(*device_, capture_buffer_memory_, nullptr);
capture_buffer_ = nullptr;
capture_buffer_memory_ = nullptr;
capture_buffer_size_ = 0;
}
void VulkanGraphicsSystem::Shutdown() { GraphicsSystem::Shutdown(); }
std::unique_ptr<CommandProcessor>
VulkanGraphicsSystem::CreateCommandProcessor() {
return std::make_unique<VulkanCommandProcessor>(this, kernel_state_);
return std::unique_ptr<CommandProcessor>(
new VulkanCommandProcessor(this, kernel_state_));
}
void VulkanGraphicsSystem::Swap(xe::ui::UIEvent* e) {
@@ -264,63 +42,9 @@ void VulkanGraphicsSystem::Swap(xe::ui::UIEvent* e) {
return;
}
// Check for pending swap.
auto& swap_state = command_processor_->swap_state();
if (display_context_->WasLost()) {
// We're crashing. Cheese it.
swap_state.pending = false;
return;
}
{
std::lock_guard<std::mutex> lock(swap_state.mutex);
if (!swap_state.pending) {
// return;
}
swap_state.pending = false;
}
if (!swap_state.front_buffer_texture) {
// Not yet ready.
return;
}
auto swap_chain = display_context_->swap_chain();
auto copy_cmd_buffer = swap_chain->copy_cmd_buffer();
auto front_buffer =
reinterpret_cast<VkImage>(swap_state.front_buffer_texture);
VkImageMemoryBarrier barrier;
std::memset(&barrier, 0, sizeof(VkImageMemoryBarrier));
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = front_buffer;
barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
vkCmdPipelineBarrier(copy_cmd_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0,
nullptr, 1, &barrier);
VkImageBlit region;
region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
region.srcOffsets[0] = {0, 0, 0};
region.srcOffsets[1] = {static_cast<int32_t>(swap_state.width),
static_cast<int32_t>(swap_state.height), 1};
region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
region.dstOffsets[0] = {0, 0, 0};
region.dstOffsets[1] = {static_cast<int32_t>(swap_chain->surface_width()),
static_cast<int32_t>(swap_chain->surface_height()),
1};
vkCmdBlitImage(copy_cmd_buffer, front_buffer, VK_IMAGE_LAYOUT_GENERAL,
swap_chain->surface_image(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region,
VK_FILTER_LINEAR);
std::lock_guard<std::mutex> lock(swap_state.mutex);
swap_state.pending = false;
}
} // namespace vulkan

View File

@@ -12,8 +12,8 @@
#include <memory>
#include "xenia/gpu/command_processor.h"
#include "xenia/gpu/graphics_system.h"
#include "xenia/ui/vulkan/vulkan_context.h"
namespace xe {
namespace gpu {
@@ -26,29 +26,16 @@ class VulkanGraphicsSystem : public GraphicsSystem {
static bool IsAvailable() { return true; }
std::string name() const override { return "Vulkan - obsolete"; }
std::string name() const override { return "Vulkan Prototype"; }
X_STATUS Setup(cpu::Processor* processor, kernel::KernelState* kernel_state,
ui::Window* target_window) override;
void Shutdown() override;
std::unique_ptr<xe::ui::RawImage> Capture() override;
private:
VkResult CreateCaptureBuffer(VkCommandBuffer cmd, VkExtent2D extents);
void DestroyCaptureBuffer();
std::unique_ptr<CommandProcessor> CreateCommandProcessor() override;
void Swap(xe::ui::UIEvent* e) override;
xe::ui::vulkan::VulkanDevice* device_ = nullptr;
xe::ui::vulkan::VulkanContext* display_context_ = nullptr;
VkCommandPool command_pool_ = nullptr;
VkBuffer capture_buffer_ = nullptr;
VkDeviceMemory capture_buffer_memory_ = nullptr;
VkDeviceSize capture_buffer_size_ = 0;
};
} // namespace vulkan

View File

@@ -1,64 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/gpu/vulkan/vulkan_shader.h"
#include "third_party/fmt/include/fmt/format.h"
#include "xenia/base/assert.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/ui/vulkan/vulkan_device.h"
#include "xenia/ui/vulkan/vulkan_util.h"
namespace xe {
namespace gpu {
namespace vulkan {
using xe::ui::vulkan::CheckResult;
VulkanShader::VulkanShader(ui::vulkan::VulkanDevice* device,
xenos::ShaderType shader_type, uint64_t data_hash,
const uint32_t* dword_ptr, uint32_t dword_count)
: Shader(shader_type, data_hash, dword_ptr, dword_count), device_(device) {}
VulkanShader::~VulkanShader() {
if (shader_module_) {
vkDestroyShaderModule(*device_, shader_module_, nullptr);
shader_module_ = nullptr;
}
}
bool VulkanShader::Prepare() {
assert_null(shader_module_);
assert_true(is_valid());
// Create the shader module.
VkShaderModuleCreateInfo shader_info;
shader_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
shader_info.pNext = nullptr;
shader_info.flags = 0;
shader_info.codeSize = translated_binary_.size();
shader_info.pCode =
reinterpret_cast<const uint32_t*>(translated_binary_.data());
auto status =
vkCreateShaderModule(*device_, &shader_info, nullptr, &shader_module_);
CheckResult(status, "vkCreateShaderModule");
char typeChar = shader_type_ == xenos::ShaderType::kPixel
? 'p'
: shader_type_ == xenos::ShaderType::kVertex ? 'v' : 'u';
device_->DbgSetObjectName(
uint64_t(shader_module_), VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT,
fmt::format("S({}): {:016X}", typeChar, ucode_data_hash()));
return status == VK_SUCCESS;
}
} // namespace vulkan
} // namespace gpu
} // namespace xe

View File

@@ -1,43 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2016 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_GPU_VULKAN_VULKAN_SHADER_H_
#define XENIA_GPU_VULKAN_VULKAN_SHADER_H_
#include <string>
#include "xenia/gpu/shader.h"
#include "xenia/ui/vulkan/vulkan_context.h"
namespace xe {
namespace gpu {
namespace vulkan {
class VulkanShader : public Shader {
public:
VulkanShader(ui::vulkan::VulkanDevice* device, xenos::ShaderType shader_type,
uint64_t data_hash, const uint32_t* dword_ptr,
uint32_t dword_count);
~VulkanShader() override;
// Available only if the shader is_valid and has been prepared.
VkShaderModule shader_module() const { return shader_module_; }
bool Prepare();
private:
ui::vulkan::VulkanDevice* device_ = nullptr;
VkShaderModule shader_module_ = nullptr;
};
} // namespace vulkan
} // namespace gpu
} // namespace xe
#endif // XENIA_GPU_VULKAN_VULKAN_SHADER_H_

View File

@@ -1,60 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/base/logging.h"
#include "xenia/base/main.h"
#include "xenia/gpu/trace_dump.h"
#include "xenia/gpu/vulkan/vulkan_command_processor.h"
#include "xenia/gpu/vulkan/vulkan_graphics_system.h"
#include "xenia/ui/vulkan/vulkan_device.h"
#include "xenia/ui/vulkan/vulkan_provider.h"
namespace xe {
namespace gpu {
namespace vulkan {
using namespace xe::gpu::xenos;
class VulkanTraceDump : public TraceDump {
public:
std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() override {
return std::unique_ptr<gpu::GraphicsSystem>(new VulkanGraphicsSystem());
}
void BeginHostCapture() override {
auto device = static_cast<const ui::vulkan::VulkanProvider*>(
graphics_system_->provider())
->device();
if (device->is_renderdoc_attached()) {
device->BeginRenderDocFrameCapture();
}
}
void EndHostCapture() override {
auto device = static_cast<const ui::vulkan::VulkanProvider*>(
graphics_system_->provider())
->device();
if (device->is_renderdoc_attached()) {
device->EndRenderDocFrameCapture();
}
}
};
int trace_dump_main(const std::vector<std::string>& args) {
VulkanTraceDump trace_dump;
return trace_dump.Main(args);
}
} // namespace vulkan
} // namespace gpu
} // namespace xe
DEFINE_ENTRY_POINT("xenia-gpu-vulkan-trace-dump",
xe::gpu::vulkan::trace_dump_main, "some.trace",
"target_trace_file");

View File

@@ -1,76 +0,0 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/base/logging.h"
#include "xenia/base/main.h"
#include "xenia/gpu/trace_viewer.h"
#include "xenia/gpu/vulkan/vulkan_command_processor.h"
#include "xenia/gpu/vulkan/vulkan_graphics_system.h"
namespace xe {
namespace gpu {
namespace vulkan {
using namespace xe::gpu::xenos;
class VulkanTraceViewer : public TraceViewer {
public:
std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() override {
return std::unique_ptr<gpu::GraphicsSystem>(new VulkanGraphicsSystem());
}
uintptr_t GetColorRenderTarget(
uint32_t pitch, xenos::MsaaSamples samples, uint32_t base,
xenos::ColorRenderTargetFormat format) override {
auto command_processor = static_cast<VulkanCommandProcessor*>(
graphics_system_->command_processor());
// return command_processor->GetColorRenderTarget(pitch, samples, base,
// format);
return 0;
}
uintptr_t GetDepthRenderTarget(
uint32_t pitch, xenos::MsaaSamples samples, uint32_t base,
xenos::DepthRenderTargetFormat format) override {
auto command_processor = static_cast<VulkanCommandProcessor*>(
graphics_system_->command_processor());
// return command_processor->GetDepthRenderTarget(pitch, samples, base,
// format);
return 0;
}
uintptr_t GetTextureEntry(const TextureInfo& texture_info,
const SamplerInfo& sampler_info) override {
auto command_processor = static_cast<VulkanCommandProcessor*>(
graphics_system_->command_processor());
// auto entry_view =
// command_processor->texture_cache()->Demand(texture_info,
// sampler_info);
// if (!entry_view) {
// return 0;
//}
// auto texture = entry_view->texture;
// return static_cast<uintptr_t>(texture->handle);
return 0;
}
};
int trace_viewer_main(const std::vector<std::string>& args) {
VulkanTraceViewer trace_viewer;
return trace_viewer.Main(args);
}
} // namespace vulkan
} // namespace gpu
} // namespace xe
DEFINE_ENTRY_POINT("xenia-gpu-vulkan-trace-viewer",
xe::gpu::vulkan::trace_viewer_main, "some.trace",
"target_trace_file");