[GPU] Move all xenos.h to gpu::xenos, disambiguate Dimension/TextureDimension
This commit is contained in:
@@ -420,7 +420,7 @@ std::pair<VkDeviceSize, VkDeviceSize> BufferCache::UploadConstantRegisters(
|
||||
|
||||
std::pair<VkBuffer, VkDeviceSize> BufferCache::UploadIndexBuffer(
|
||||
VkCommandBuffer command_buffer, uint32_t source_addr,
|
||||
uint32_t source_length, IndexFormat format, VkFence fence) {
|
||||
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) {
|
||||
@@ -439,23 +439,23 @@ std::pair<VkBuffer, VkDeviceSize> BufferCache::UploadIndexBuffer(
|
||||
// primitive reset indices to something Vulkan understands.
|
||||
// TODO(benvanik): memcpy then use compute shaders to swap?
|
||||
if (prim_reset_enabled) {
|
||||
if (format == IndexFormat::kInt16) {
|
||||
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 == IndexFormat::kInt32) {
|
||||
} 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 == IndexFormat::kInt16) {
|
||||
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 == IndexFormat::kInt32) {
|
||||
} 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);
|
||||
@@ -485,7 +485,7 @@ std::pair<VkBuffer, VkDeviceSize> BufferCache::UploadIndexBuffer(
|
||||
|
||||
std::pair<VkBuffer, VkDeviceSize> BufferCache::UploadVertexBuffer(
|
||||
VkCommandBuffer command_buffer, uint32_t source_addr,
|
||||
uint32_t source_length, Endian endian, VkFence fence) {
|
||||
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};
|
||||
@@ -518,11 +518,11 @@ std::pair<VkBuffer, VkDeviceSize> BufferCache::UploadVertexBuffer(
|
||||
|
||||
// Copy data into the buffer.
|
||||
// TODO(benvanik): memcpy then use compute shaders to swap?
|
||||
if (endian == Endian::k8in32) {
|
||||
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 == Endian::k16in32) {
|
||||
} 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 {
|
||||
|
||||
@@ -78,7 +78,7 @@ class BufferCache {
|
||||
// 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, IndexFormat format, VkFence fence);
|
||||
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.
|
||||
@@ -86,7 +86,7 @@ class BufferCache {
|
||||
// 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, Endian endian, VkFence fence);
|
||||
uint32_t source_length, xenos::Endian endian, VkFence fence);
|
||||
|
||||
// Prepares and returns a vertex descriptor set.
|
||||
VkDescriptorSet PrepareVertexSet(
|
||||
|
||||
@@ -203,7 +203,7 @@ void PipelineCache::Shutdown() {
|
||||
}
|
||||
}
|
||||
|
||||
VulkanShader* PipelineCache::LoadShader(ShaderType shader_type,
|
||||
VulkanShader* PipelineCache::LoadShader(xenos::ShaderType shader_type,
|
||||
uint32_t guest_address,
|
||||
const uint32_t* host_address,
|
||||
uint32_t dword_count) {
|
||||
@@ -228,7 +228,7 @@ VulkanShader* PipelineCache::LoadShader(ShaderType shader_type,
|
||||
PipelineCache::UpdateStatus PipelineCache::ConfigurePipeline(
|
||||
VkCommandBuffer command_buffer, const RenderState* render_state,
|
||||
VulkanShader* vertex_shader, VulkanShader* pixel_shader,
|
||||
PrimitiveType primitive_type, VkPipeline* pipeline_out) {
|
||||
xenos::PrimitiveType primitive_type, VkPipeline* pipeline_out) {
|
||||
#if FINE_GRAINED_DRAW_SCOPES
|
||||
SCOPE_profile_cpu_f("gpu");
|
||||
#endif // FINE_GRAINED_DRAW_SCOPES
|
||||
@@ -380,7 +380,7 @@ bool PipelineCache::TranslateShader(VulkanShader* shader,
|
||||
|
||||
if (shader->is_valid()) {
|
||||
XELOGGPU("Generated {} shader ({}b) - hash {:016X}:\n{}\n",
|
||||
shader->type() == ShaderType::kVertex ? "vertex" : "pixel",
|
||||
shader->type() == xenos::ShaderType::kVertex ? "vertex" : "pixel",
|
||||
shader->ucode_dword_count() * 4, shader->ucode_data_hash(),
|
||||
shader->ucode_disassembly());
|
||||
}
|
||||
@@ -529,33 +529,33 @@ void PipelineCache::DumpShaderDisasmNV(
|
||||
vkDestroyPipelineCache(*device_, dummy_pipeline_cache, nullptr);
|
||||
}
|
||||
|
||||
VkShaderModule PipelineCache::GetGeometryShader(PrimitiveType primitive_type,
|
||||
bool is_line_mode) {
|
||||
VkShaderModule PipelineCache::GetGeometryShader(
|
||||
xenos::PrimitiveType primitive_type, bool is_line_mode) {
|
||||
switch (primitive_type) {
|
||||
case PrimitiveType::kLineList:
|
||||
case PrimitiveType::kLineLoop:
|
||||
case PrimitiveType::kLineStrip:
|
||||
case PrimitiveType::kTriangleList:
|
||||
case PrimitiveType::kTriangleFan:
|
||||
case PrimitiveType::kTriangleStrip:
|
||||
case xenos::PrimitiveType::kLineList:
|
||||
case xenos::PrimitiveType::kLineLoop:
|
||||
case xenos::PrimitiveType::kLineStrip:
|
||||
case xenos::PrimitiveType::kTriangleList:
|
||||
case xenos::PrimitiveType::kTriangleFan:
|
||||
case xenos::PrimitiveType::kTriangleStrip:
|
||||
// Supported directly - no need to emulate.
|
||||
return nullptr;
|
||||
case PrimitiveType::kPointList:
|
||||
case xenos::PrimitiveType::kPointList:
|
||||
return geometry_shaders_.point_list;
|
||||
case PrimitiveType::kTriangleWithWFlags:
|
||||
case xenos::PrimitiveType::kTriangleWithWFlags:
|
||||
assert_always("Unknown geometry type");
|
||||
return nullptr;
|
||||
case PrimitiveType::kRectangleList:
|
||||
case xenos::PrimitiveType::kRectangleList:
|
||||
return geometry_shaders_.rect_list;
|
||||
case PrimitiveType::kQuadList:
|
||||
case xenos::PrimitiveType::kQuadList:
|
||||
return is_line_mode ? geometry_shaders_.line_quad_list
|
||||
: geometry_shaders_.quad_list;
|
||||
case PrimitiveType::kQuadStrip:
|
||||
case xenos::PrimitiveType::kQuadStrip:
|
||||
// TODO(benvanik): quad strip geometry shader.
|
||||
assert_always("Quad strips not implemented");
|
||||
return nullptr;
|
||||
case PrimitiveType::kTrianglePatch:
|
||||
case PrimitiveType::kQuadPatch:
|
||||
case xenos::PrimitiveType::kTrianglePatch:
|
||||
case xenos::PrimitiveType::kQuadPatch:
|
||||
assert_always("Tessellation is not implemented");
|
||||
return nullptr;
|
||||
default:
|
||||
@@ -640,18 +640,18 @@ bool PipelineCache::SetDynamicState(VkCommandBuffer command_buffer,
|
||||
XE_GPU_REG_PA_CL_VPORT_ZSCALE);
|
||||
// RB_SURFACE_INFO
|
||||
auto surface_msaa =
|
||||
static_cast<MsaaSamples>((regs.rb_surface_info >> 16) & 0x3);
|
||||
static_cast<xenos::MsaaSamples>((regs.rb_surface_info >> 16) & 0x3);
|
||||
|
||||
// Apply a multiplier to emulate MSAA.
|
||||
float window_width_scalar = 1;
|
||||
float window_height_scalar = 1;
|
||||
switch (surface_msaa) {
|
||||
case MsaaSamples::k1X:
|
||||
case xenos::MsaaSamples::k1X:
|
||||
break;
|
||||
case MsaaSamples::k2X:
|
||||
case xenos::MsaaSamples::k2X:
|
||||
window_height_scalar = 2;
|
||||
break;
|
||||
case MsaaSamples::k4X:
|
||||
case xenos::MsaaSamples::k4X:
|
||||
window_width_scalar = window_height_scalar = 2;
|
||||
break;
|
||||
}
|
||||
@@ -954,7 +954,7 @@ bool PipelineCache::SetShadowRegisterArray(uint32_t* dest, uint32_t num,
|
||||
|
||||
PipelineCache::UpdateStatus PipelineCache::UpdateState(
|
||||
VulkanShader* vertex_shader, VulkanShader* pixel_shader,
|
||||
PrimitiveType primitive_type) {
|
||||
xenos::PrimitiveType primitive_type) {
|
||||
bool mismatch = false;
|
||||
|
||||
// Reset hash so we can build it up.
|
||||
@@ -1035,7 +1035,7 @@ PipelineCache::UpdateStatus PipelineCache::UpdateRenderTargetState() {
|
||||
|
||||
PipelineCache::UpdateStatus PipelineCache::UpdateShaderStages(
|
||||
VulkanShader* vertex_shader, VulkanShader* pixel_shader,
|
||||
PrimitiveType primitive_type) {
|
||||
xenos::PrimitiveType primitive_type) {
|
||||
auto& regs = update_shader_stages_regs_;
|
||||
|
||||
// These are the constant base addresses/ranges for shaders.
|
||||
@@ -1150,7 +1150,7 @@ PipelineCache::UpdateStatus PipelineCache::UpdateVertexInputState(
|
||||
}
|
||||
|
||||
PipelineCache::UpdateStatus PipelineCache::UpdateInputAssemblyState(
|
||||
PrimitiveType primitive_type) {
|
||||
xenos::PrimitiveType primitive_type) {
|
||||
auto& regs = update_input_assembly_state_regs_;
|
||||
auto& state_info = update_input_assembly_state_info_;
|
||||
|
||||
@@ -1172,35 +1172,35 @@ PipelineCache::UpdateStatus PipelineCache::UpdateInputAssemblyState(
|
||||
state_info.flags = 0;
|
||||
|
||||
switch (primitive_type) {
|
||||
case PrimitiveType::kPointList:
|
||||
case xenos::PrimitiveType::kPointList:
|
||||
state_info.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
|
||||
break;
|
||||
case PrimitiveType::kLineList:
|
||||
case xenos::PrimitiveType::kLineList:
|
||||
state_info.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
|
||||
break;
|
||||
case PrimitiveType::kLineStrip:
|
||||
case xenos::PrimitiveType::kLineStrip:
|
||||
state_info.topology = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
|
||||
break;
|
||||
case PrimitiveType::kLineLoop:
|
||||
case xenos::PrimitiveType::kLineLoop:
|
||||
state_info.topology = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
|
||||
break;
|
||||
case PrimitiveType::kTriangleList:
|
||||
case xenos::PrimitiveType::kTriangleList:
|
||||
state_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
break;
|
||||
case PrimitiveType::kTriangleStrip:
|
||||
case xenos::PrimitiveType::kTriangleStrip:
|
||||
state_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||
break;
|
||||
case PrimitiveType::kTriangleFan:
|
||||
case xenos::PrimitiveType::kTriangleFan:
|
||||
state_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
|
||||
break;
|
||||
case PrimitiveType::kRectangleList:
|
||||
case xenos::PrimitiveType::kRectangleList:
|
||||
state_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
|
||||
break;
|
||||
case PrimitiveType::kQuadList:
|
||||
case xenos::PrimitiveType::kQuadList:
|
||||
state_info.topology = VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY;
|
||||
break;
|
||||
default:
|
||||
case PrimitiveType::kTriangleWithWFlags:
|
||||
case xenos::PrimitiveType::kTriangleWithWFlags:
|
||||
XELOGE("unsupported primitive type {}", primitive_type);
|
||||
assert_unhandled_case(primitive_type);
|
||||
return UpdateStatus::kError;
|
||||
@@ -1243,7 +1243,7 @@ PipelineCache::UpdateStatus PipelineCache::UpdateViewportState() {
|
||||
}
|
||||
|
||||
PipelineCache::UpdateStatus PipelineCache::UpdateRasterizationState(
|
||||
PrimitiveType primitive_type) {
|
||||
xenos::PrimitiveType primitive_type) {
|
||||
auto& regs = update_rasterization_state_regs_;
|
||||
auto& state_info = update_rasterization_state_info_;
|
||||
|
||||
@@ -1341,10 +1341,10 @@ PipelineCache::UpdateStatus PipelineCache::UpdateRasterizationState(
|
||||
} else {
|
||||
state_info.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
}
|
||||
if (primitive_type == PrimitiveType::kRectangleList) {
|
||||
if (primitive_type == xenos::PrimitiveType::kRectangleList) {
|
||||
// Rectangle lists aren't culled. There may be other things they skip too.
|
||||
state_info.cullMode = VK_CULL_MODE_NONE;
|
||||
} else if (primitive_type == PrimitiveType::kPointList) {
|
||||
} else if (primitive_type == xenos::PrimitiveType::kPointList) {
|
||||
// Face culling doesn't apply to point primitives.
|
||||
state_info.cullMode = VK_CULL_MODE_NONE;
|
||||
}
|
||||
@@ -1385,15 +1385,15 @@ PipelineCache::UpdateStatus PipelineCache::UpdateMultisampleState() {
|
||||
// all sampled from the pixel center.
|
||||
if (cvars::vulkan_native_msaa) {
|
||||
auto msaa_num_samples =
|
||||
static_cast<MsaaSamples>((regs.rb_surface_info >> 16) & 0x3);
|
||||
static_cast<xenos::MsaaSamples>((regs.rb_surface_info >> 16) & 0x3);
|
||||
switch (msaa_num_samples) {
|
||||
case MsaaSamples::k1X:
|
||||
case xenos::MsaaSamples::k1X:
|
||||
state_info.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
break;
|
||||
case MsaaSamples::k2X:
|
||||
case xenos::MsaaSamples::k2X:
|
||||
state_info.rasterizationSamples = VK_SAMPLE_COUNT_2_BIT;
|
||||
break;
|
||||
case MsaaSamples::k4X:
|
||||
case xenos::MsaaSamples::k4X:
|
||||
state_info.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -47,8 +47,9 @@ class PipelineCache {
|
||||
void Shutdown();
|
||||
|
||||
// Loads a shader from the cache, possibly translating it.
|
||||
VulkanShader* LoadShader(ShaderType shader_type, uint32_t guest_address,
|
||||
const uint32_t* host_address, uint32_t dword_count);
|
||||
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,
|
||||
@@ -59,7 +60,7 @@ class PipelineCache {
|
||||
const RenderState* render_state,
|
||||
VulkanShader* vertex_shader,
|
||||
VulkanShader* pixel_shader,
|
||||
PrimitiveType primitive_type,
|
||||
xenos::PrimitiveType primitive_type,
|
||||
VkPipeline* pipeline_out);
|
||||
|
||||
// Sets required dynamic state on the command buffer.
|
||||
@@ -85,7 +86,7 @@ class PipelineCache {
|
||||
|
||||
// Gets a geometry shader used to emulate the given primitive type.
|
||||
// Returns nullptr if the primitive doesn't need to be emulated.
|
||||
VkShaderModule GetGeometryShader(PrimitiveType primitive_type,
|
||||
VkShaderModule GetGeometryShader(xenos::PrimitiveType primitive_type,
|
||||
bool is_line_mode);
|
||||
|
||||
RegisterFile* register_file_ = nullptr;
|
||||
@@ -131,16 +132,16 @@ class PipelineCache {
|
||||
private:
|
||||
UpdateStatus UpdateState(VulkanShader* vertex_shader,
|
||||
VulkanShader* pixel_shader,
|
||||
PrimitiveType primitive_type);
|
||||
xenos::PrimitiveType primitive_type);
|
||||
|
||||
UpdateStatus UpdateRenderTargetState();
|
||||
UpdateStatus UpdateShaderStages(VulkanShader* vertex_shader,
|
||||
VulkanShader* pixel_shader,
|
||||
PrimitiveType primitive_type);
|
||||
xenos::PrimitiveType primitive_type);
|
||||
UpdateStatus UpdateVertexInputState(VulkanShader* vertex_shader);
|
||||
UpdateStatus UpdateInputAssemblyState(PrimitiveType primitive_type);
|
||||
UpdateStatus UpdateInputAssemblyState(xenos::PrimitiveType primitive_type);
|
||||
UpdateStatus UpdateViewportState();
|
||||
UpdateStatus UpdateRasterizationState(PrimitiveType primitive_type);
|
||||
UpdateStatus UpdateRasterizationState(xenos::PrimitiveType primitive_type);
|
||||
UpdateStatus UpdateMultisampleState();
|
||||
UpdateStatus UpdateDepthStencilState();
|
||||
UpdateStatus UpdateColorBlendState();
|
||||
@@ -167,7 +168,7 @@ class PipelineCache {
|
||||
} update_render_targets_regs_;
|
||||
|
||||
struct UpdateShaderStagesRegisters {
|
||||
PrimitiveType primitive_type;
|
||||
xenos::PrimitiveType primitive_type;
|
||||
uint32_t pa_su_sc_mode_cntl;
|
||||
reg::SQ_PROGRAM_CNTL sq_program_cntl;
|
||||
VulkanShader* vertex_shader;
|
||||
@@ -191,7 +192,7 @@ class PipelineCache {
|
||||
update_vertex_input_state_attrib_descrs_[96];
|
||||
|
||||
struct UpdateInputAssemblyStateRegisters {
|
||||
PrimitiveType primitive_type;
|
||||
xenos::PrimitiveType primitive_type;
|
||||
uint32_t pa_su_sc_mode_cntl;
|
||||
uint32_t multi_prim_ib_reset_index;
|
||||
|
||||
@@ -221,7 +222,7 @@ class PipelineCache {
|
||||
VkPipelineViewportStateCreateInfo update_viewport_state_info_;
|
||||
|
||||
struct UpdateRasterizationStateRegisters {
|
||||
PrimitiveType primitive_type;
|
||||
xenos::PrimitiveType primitive_type;
|
||||
uint32_t pa_cl_clip_cntl;
|
||||
uint32_t pa_su_sc_mode_cntl;
|
||||
uint32_t pa_sc_screen_scissor_tl;
|
||||
|
||||
@@ -29,41 +29,43 @@ using xe::ui::vulkan::CheckResult;
|
||||
|
||||
constexpr uint32_t kEdramBufferCapacity = 10 * 1024 * 1024;
|
||||
|
||||
ColorRenderTargetFormat GetBaseRTFormat(ColorRenderTargetFormat format) {
|
||||
xenos::ColorRenderTargetFormat GetBaseRTFormat(
|
||||
xenos::ColorRenderTargetFormat format) {
|
||||
switch (format) {
|
||||
case ColorRenderTargetFormat::k_8_8_8_8_GAMMA:
|
||||
return ColorRenderTargetFormat::k_8_8_8_8;
|
||||
case ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10:
|
||||
return ColorRenderTargetFormat::k_2_10_10_10;
|
||||
case ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16:
|
||||
return ColorRenderTargetFormat::k_2_10_10_10_FLOAT;
|
||||
case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA:
|
||||
return xenos::ColorRenderTargetFormat::k_8_8_8_8;
|
||||
case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10:
|
||||
return xenos::ColorRenderTargetFormat::k_2_10_10_10;
|
||||
case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16:
|
||||
return xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT;
|
||||
default:
|
||||
return format;
|
||||
}
|
||||
}
|
||||
|
||||
VkFormat ColorRenderTargetFormatToVkFormat(ColorRenderTargetFormat format) {
|
||||
VkFormat ColorRenderTargetFormatToVkFormat(
|
||||
xenos::ColorRenderTargetFormat format) {
|
||||
switch (format) {
|
||||
case ColorRenderTargetFormat::k_8_8_8_8:
|
||||
case ColorRenderTargetFormat::k_8_8_8_8_GAMMA:
|
||||
case xenos::ColorRenderTargetFormat::k_8_8_8_8:
|
||||
case xenos::ColorRenderTargetFormat::k_8_8_8_8_GAMMA:
|
||||
return VK_FORMAT_R8G8B8A8_UNORM;
|
||||
case ColorRenderTargetFormat::k_2_10_10_10:
|
||||
case ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10:
|
||||
case xenos::ColorRenderTargetFormat::k_2_10_10_10:
|
||||
case xenos::ColorRenderTargetFormat::k_2_10_10_10_AS_10_10_10_10:
|
||||
return VK_FORMAT_A2R10G10B10_UNORM_PACK32;
|
||||
case ColorRenderTargetFormat::k_2_10_10_10_FLOAT:
|
||||
case ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16:
|
||||
case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT:
|
||||
case xenos::ColorRenderTargetFormat::k_2_10_10_10_FLOAT_AS_16_16_16_16:
|
||||
return VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
case ColorRenderTargetFormat::k_16_16:
|
||||
case xenos::ColorRenderTargetFormat::k_16_16:
|
||||
return VK_FORMAT_R16G16_UNORM;
|
||||
case ColorRenderTargetFormat::k_16_16_16_16:
|
||||
case xenos::ColorRenderTargetFormat::k_16_16_16_16:
|
||||
return VK_FORMAT_R16G16B16A16_UNORM;
|
||||
case ColorRenderTargetFormat::k_16_16_FLOAT:
|
||||
case xenos::ColorRenderTargetFormat::k_16_16_FLOAT:
|
||||
return VK_FORMAT_R16G16_SFLOAT;
|
||||
case ColorRenderTargetFormat::k_16_16_16_16_FLOAT:
|
||||
case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT:
|
||||
return VK_FORMAT_R16G16B16A16_SFLOAT;
|
||||
case ColorRenderTargetFormat::k_32_FLOAT:
|
||||
case xenos::ColorRenderTargetFormat::k_32_FLOAT:
|
||||
return VK_FORMAT_R32_SFLOAT;
|
||||
case ColorRenderTargetFormat::k_32_32_FLOAT:
|
||||
case xenos::ColorRenderTargetFormat::k_32_32_FLOAT:
|
||||
return VK_FORMAT_R32G32_SFLOAT;
|
||||
default:
|
||||
assert_unhandled_case(key.edram_format);
|
||||
@@ -71,11 +73,12 @@ VkFormat ColorRenderTargetFormatToVkFormat(ColorRenderTargetFormat format) {
|
||||
}
|
||||
}
|
||||
|
||||
VkFormat DepthRenderTargetFormatToVkFormat(DepthRenderTargetFormat format) {
|
||||
VkFormat DepthRenderTargetFormatToVkFormat(
|
||||
xenos::DepthRenderTargetFormat format) {
|
||||
switch (format) {
|
||||
case DepthRenderTargetFormat::kD24S8:
|
||||
case xenos::DepthRenderTargetFormat::kD24S8:
|
||||
return VK_FORMAT_D24_UNORM_S8_UINT;
|
||||
case DepthRenderTargetFormat::kD24FS8:
|
||||
case xenos::DepthRenderTargetFormat::kD24FS8:
|
||||
// Vulkan doesn't support 24-bit floats, so just promote it to 32-bit
|
||||
return VK_FORMAT_D32_SFLOAT_S8_UINT;
|
||||
default:
|
||||
@@ -161,12 +164,13 @@ VkResult CachedTileView::Initialize(VkCommandBuffer command_buffer) {
|
||||
VkFormat vulkan_format = VK_FORMAT_UNDEFINED;
|
||||
uint32_t bpp = 4;
|
||||
if (key.color_or_depth) {
|
||||
auto edram_format = static_cast<ColorRenderTargetFormat>(key.edram_format);
|
||||
auto edram_format =
|
||||
static_cast<xenos::ColorRenderTargetFormat>(key.edram_format);
|
||||
vulkan_format = ColorRenderTargetFormatToVkFormat(edram_format);
|
||||
switch (edram_format) {
|
||||
case ColorRenderTargetFormat::k_16_16_16_16:
|
||||
case ColorRenderTargetFormat::k_16_16_16_16_FLOAT:
|
||||
case ColorRenderTargetFormat::k_32_32_FLOAT:
|
||||
case xenos::ColorRenderTargetFormat::k_16_16_16_16:
|
||||
case xenos::ColorRenderTargetFormat::k_16_16_16_16_FLOAT:
|
||||
case xenos::ColorRenderTargetFormat::k_32_32_FLOAT:
|
||||
bpp = 8;
|
||||
break;
|
||||
default:
|
||||
@@ -174,7 +178,8 @@ VkResult CachedTileView::Initialize(VkCommandBuffer command_buffer) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
auto edram_format = static_cast<DepthRenderTargetFormat>(key.edram_format);
|
||||
auto edram_format =
|
||||
static_cast<xenos::DepthRenderTargetFormat>(key.edram_format);
|
||||
vulkan_format = DepthRenderTargetFormatToVkFormat(edram_format);
|
||||
}
|
||||
assert_true(vulkan_format != VK_FORMAT_UNDEFINED);
|
||||
@@ -196,15 +201,15 @@ VkResult CachedTileView::Initialize(VkCommandBuffer command_buffer) {
|
||||
image_info.mipLevels = 1;
|
||||
image_info.arrayLayers = 1;
|
||||
if (cvars::vulkan_native_msaa) {
|
||||
auto msaa_samples = static_cast<MsaaSamples>(key.msaa_samples);
|
||||
auto msaa_samples = static_cast<xenos::MsaaSamples>(key.msaa_samples);
|
||||
switch (msaa_samples) {
|
||||
case MsaaSamples::k1X:
|
||||
case xenos::MsaaSamples::k1X:
|
||||
image_info.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
break;
|
||||
case MsaaSamples::k2X:
|
||||
case xenos::MsaaSamples::k2X:
|
||||
image_info.samples = VK_SAMPLE_COUNT_2_BIT;
|
||||
break;
|
||||
case MsaaSamples::k4X:
|
||||
case xenos::MsaaSamples::k4X:
|
||||
image_info.samples = VK_SAMPLE_COUNT_4_BIT;
|
||||
break;
|
||||
default:
|
||||
@@ -371,12 +376,14 @@ bool CachedFramebuffer::IsCompatible(
|
||||
const RenderConfiguration& desired_config) const {
|
||||
// We already know all render pass things line up, so let's verify dimensions,
|
||||
// edram offsets, etc. We need an exact match.
|
||||
uint32_t surface_pitch_px = desired_config.surface_msaa != MsaaSamples::k4X
|
||||
? desired_config.surface_pitch_px
|
||||
: desired_config.surface_pitch_px * 2;
|
||||
uint32_t surface_height_px = desired_config.surface_msaa == MsaaSamples::k1X
|
||||
? desired_config.surface_height_px
|
||||
: desired_config.surface_height_px * 2;
|
||||
uint32_t surface_pitch_px =
|
||||
desired_config.surface_msaa != xenos::MsaaSamples::k4X
|
||||
? desired_config.surface_pitch_px
|
||||
: desired_config.surface_pitch_px * 2;
|
||||
uint32_t surface_height_px =
|
||||
desired_config.surface_msaa == xenos::MsaaSamples::k1X
|
||||
? desired_config.surface_height_px
|
||||
: desired_config.surface_height_px * 2;
|
||||
surface_pitch_px = std::min(surface_pitch_px, 2560u);
|
||||
surface_height_px = std::min(surface_height_px, 2560u);
|
||||
if (surface_pitch_px != width || surface_height_px != height) {
|
||||
@@ -426,13 +433,13 @@ VkResult CachedRenderPass::Initialize() {
|
||||
VkSampleCountFlagBits sample_count;
|
||||
if (cvars::vulkan_native_msaa) {
|
||||
switch (config.surface_msaa) {
|
||||
case MsaaSamples::k1X:
|
||||
case xenos::MsaaSamples::k1X:
|
||||
sample_count = VK_SAMPLE_COUNT_1_BIT;
|
||||
break;
|
||||
case MsaaSamples::k2X:
|
||||
case xenos::MsaaSamples::k2X:
|
||||
sample_count = VK_SAMPLE_COUNT_2_BIT;
|
||||
break;
|
||||
case MsaaSamples::k4X:
|
||||
case xenos::MsaaSamples::k4X:
|
||||
sample_count = VK_SAMPLE_COUNT_4_BIT;
|
||||
break;
|
||||
default:
|
||||
@@ -759,10 +766,10 @@ const RenderState* RenderCache::BeginRenderPass(VkCommandBuffer command_buffer,
|
||||
render_pass_begin_info.renderArea.extent.width = config->surface_pitch_px;
|
||||
render_pass_begin_info.renderArea.extent.height = config->surface_height_px;
|
||||
|
||||
if (config->surface_msaa == MsaaSamples::k2X) {
|
||||
if (config->surface_msaa == xenos::MsaaSamples::k2X) {
|
||||
render_pass_begin_info.renderArea.extent.height =
|
||||
std::min(config->surface_height_px * 2, 2560u);
|
||||
} else if (config->surface_msaa == MsaaSamples::k4X) {
|
||||
} else if (config->surface_msaa == xenos::MsaaSamples::k4X) {
|
||||
render_pass_begin_info.renderArea.extent.width *= 2;
|
||||
render_pass_begin_info.renderArea.extent.height =
|
||||
std::min(config->surface_height_px * 2, 2560u);
|
||||
@@ -822,7 +829,7 @@ bool RenderCache::ParseConfiguration(RenderConfiguration* config) {
|
||||
} else {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
config->color[i].edram_base = 0;
|
||||
config->color[i].format = ColorRenderTargetFormat::k_8_8_8_8;
|
||||
config->color[i].format = xenos::ColorRenderTargetFormat::k_8_8_8_8;
|
||||
config->color[i].used = false;
|
||||
}
|
||||
}
|
||||
@@ -834,7 +841,7 @@ bool RenderCache::ParseConfiguration(RenderConfiguration* config) {
|
||||
config->depth_stencil.format = regs.rb_depth_info.depth_format;
|
||||
} else {
|
||||
config->depth_stencil.edram_base = 0;
|
||||
config->depth_stencil.format = DepthRenderTargetFormat::kD24S8;
|
||||
config->depth_stencil.format = xenos::DepthRenderTargetFormat::kD24S8;
|
||||
config->depth_stencil.used = false;
|
||||
}
|
||||
|
||||
@@ -886,8 +893,10 @@ bool RenderCache::ConfigureRenderPass(VkCommandBuffer command_buffer,
|
||||
|
||||
// If no framebuffer was found in the cache create a new one.
|
||||
if (!framebuffer) {
|
||||
uint32_t tile_width = config->surface_msaa == MsaaSamples::k4X ? 40 : 80;
|
||||
uint32_t tile_height = config->surface_msaa != MsaaSamples::k1X ? 8 : 16;
|
||||
uint32_t tile_width =
|
||||
config->surface_msaa == xenos::MsaaSamples::k4X ? 40 : 80;
|
||||
uint32_t tile_height =
|
||||
config->surface_msaa != xenos::MsaaSamples::k1X ? 8 : 16;
|
||||
|
||||
CachedTileView* target_color_attachments[4] = {nullptr, nullptr, nullptr,
|
||||
nullptr};
|
||||
@@ -930,10 +939,10 @@ bool RenderCache::ConfigureRenderPass(VkCommandBuffer command_buffer,
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t surface_pitch_px = config->surface_msaa != MsaaSamples::k4X
|
||||
uint32_t surface_pitch_px = config->surface_msaa != xenos::MsaaSamples::k4X
|
||||
? config->surface_pitch_px
|
||||
: config->surface_pitch_px * 2;
|
||||
uint32_t surface_height_px = config->surface_msaa == MsaaSamples::k1X
|
||||
uint32_t surface_height_px = config->surface_msaa == xenos::MsaaSamples::k1X
|
||||
? config->surface_height_px
|
||||
: config->surface_height_px * 2;
|
||||
surface_pitch_px = std::min(surface_pitch_px, 2560u);
|
||||
@@ -958,16 +967,16 @@ bool RenderCache::ConfigureRenderPass(VkCommandBuffer command_buffer,
|
||||
}
|
||||
|
||||
CachedTileView* RenderCache::FindTileView(uint32_t base, uint32_t pitch,
|
||||
MsaaSamples samples,
|
||||
xenos::MsaaSamples samples,
|
||||
bool color_or_depth,
|
||||
uint32_t format) {
|
||||
uint32_t tile_width = samples == MsaaSamples::k4X ? 40 : 80;
|
||||
uint32_t tile_height = samples != MsaaSamples::k1X ? 8 : 16;
|
||||
uint32_t tile_width = samples == xenos::MsaaSamples::k4X ? 40 : 80;
|
||||
uint32_t tile_height = samples != xenos::MsaaSamples::k1X ? 8 : 16;
|
||||
|
||||
if (color_or_depth) {
|
||||
// Adjust similar formats for easier matching.
|
||||
format = static_cast<uint32_t>(
|
||||
GetBaseRTFormat(static_cast<ColorRenderTargetFormat>(format)));
|
||||
GetBaseRTFormat(static_cast<xenos::ColorRenderTargetFormat>(format)));
|
||||
}
|
||||
|
||||
TileViewKey key;
|
||||
@@ -1011,9 +1020,9 @@ void RenderCache::UpdateTileView(VkCommandBuffer command_buffer,
|
||||
CachedTileView* view, bool load,
|
||||
bool insert_barrier) {
|
||||
uint32_t tile_width =
|
||||
view->key.msaa_samples == uint16_t(MsaaSamples::k4X) ? 40 : 80;
|
||||
view->key.msaa_samples == uint16_t(xenos::MsaaSamples::k4X) ? 40 : 80;
|
||||
uint32_t tile_height =
|
||||
view->key.msaa_samples != uint16_t(MsaaSamples::k1X) ? 8 : 16;
|
||||
view->key.msaa_samples != uint16_t(xenos::MsaaSamples::k1X) ? 8 : 16;
|
||||
|
||||
if (insert_barrier) {
|
||||
VkBufferMemoryBarrier barrier;
|
||||
@@ -1196,7 +1205,7 @@ void RenderCache::RawCopyToImage(VkCommandBuffer command_buffer,
|
||||
|
||||
void RenderCache::BlitToImage(VkCommandBuffer command_buffer,
|
||||
uint32_t edram_base, uint32_t pitch,
|
||||
uint32_t height, MsaaSamples num_samples,
|
||||
uint32_t height, xenos::MsaaSamples num_samples,
|
||||
VkImage image, VkImageLayout image_layout,
|
||||
bool color_or_depth, uint32_t format,
|
||||
VkFilter filter, VkOffset3D offset,
|
||||
@@ -1204,11 +1213,11 @@ void RenderCache::BlitToImage(VkCommandBuffer command_buffer,
|
||||
if (color_or_depth) {
|
||||
// Adjust similar formats for easier matching.
|
||||
format = static_cast<uint32_t>(
|
||||
GetBaseRTFormat(static_cast<ColorRenderTargetFormat>(format)));
|
||||
GetBaseRTFormat(static_cast<xenos::ColorRenderTargetFormat>(format)));
|
||||
}
|
||||
|
||||
uint32_t tile_width = num_samples == MsaaSamples::k4X ? 40 : 80;
|
||||
uint32_t tile_height = num_samples != MsaaSamples::k1X ? 8 : 16;
|
||||
uint32_t tile_width = num_samples == xenos::MsaaSamples::k4X ? 40 : 80;
|
||||
uint32_t tile_height = num_samples != xenos::MsaaSamples::k1X ? 8 : 16;
|
||||
|
||||
// Grab a tile view that represents the source image.
|
||||
TileViewKey key;
|
||||
@@ -1300,17 +1309,18 @@ void RenderCache::BlitToImage(VkCommandBuffer command_buffer,
|
||||
|
||||
void RenderCache::ClearEDRAMColor(VkCommandBuffer command_buffer,
|
||||
uint32_t edram_base,
|
||||
ColorRenderTargetFormat format,
|
||||
xenos::ColorRenderTargetFormat format,
|
||||
uint32_t pitch, uint32_t height,
|
||||
MsaaSamples num_samples, float* color) {
|
||||
xenos::MsaaSamples num_samples,
|
||||
float* color) {
|
||||
// TODO: For formats <= 4 bpp, we can directly fill the EDRAM buffer. Just
|
||||
// need to detect this and calculate a value.
|
||||
|
||||
// Adjust similar formats for easier matching.
|
||||
format = GetBaseRTFormat(static_cast<ColorRenderTargetFormat>(format));
|
||||
format = GetBaseRTFormat(static_cast<xenos::ColorRenderTargetFormat>(format));
|
||||
|
||||
uint32_t tile_width = num_samples == MsaaSamples::k4X ? 40 : 80;
|
||||
uint32_t tile_height = num_samples != MsaaSamples::k1X ? 8 : 16;
|
||||
uint32_t tile_width = num_samples == xenos::MsaaSamples::k4X ? 40 : 80;
|
||||
uint32_t tile_height = num_samples != xenos::MsaaSamples::k1X ? 8 : 16;
|
||||
|
||||
// Grab a tile view (as we need to clear an image first)
|
||||
TileViewKey key;
|
||||
@@ -1338,15 +1348,15 @@ void RenderCache::ClearEDRAMColor(VkCommandBuffer command_buffer,
|
||||
|
||||
void RenderCache::ClearEDRAMDepthStencil(VkCommandBuffer command_buffer,
|
||||
uint32_t edram_base,
|
||||
DepthRenderTargetFormat format,
|
||||
xenos::DepthRenderTargetFormat format,
|
||||
uint32_t pitch, uint32_t height,
|
||||
MsaaSamples num_samples, float depth,
|
||||
uint32_t stencil) {
|
||||
xenos::MsaaSamples num_samples,
|
||||
float depth, uint32_t stencil) {
|
||||
// TODO: For formats <= 4 bpp, we can directly fill the EDRAM buffer. Just
|
||||
// need to detect this and calculate a value.
|
||||
|
||||
uint32_t tile_width = num_samples == MsaaSamples::k4X ? 40 : 80;
|
||||
uint32_t tile_height = num_samples != MsaaSamples::k1X ? 8 : 16;
|
||||
uint32_t tile_width = num_samples == xenos::MsaaSamples::k4X ? 40 : 80;
|
||||
uint32_t tile_height = num_samples != xenos::MsaaSamples::k1X ? 8 : 16;
|
||||
|
||||
// Grab a tile view (as we need to clear an image first)
|
||||
TileViewKey key;
|
||||
|
||||
@@ -101,18 +101,18 @@ struct RenderConfiguration {
|
||||
// ESTIMATED target surface height multiplied by MSAA, in pixels.
|
||||
uint32_t surface_height_px;
|
||||
// Surface MSAA setting.
|
||||
MsaaSamples surface_msaa;
|
||||
xenos::MsaaSamples surface_msaa;
|
||||
// Color attachments for the 4 render targets.
|
||||
struct {
|
||||
bool used;
|
||||
uint32_t edram_base;
|
||||
ColorRenderTargetFormat format;
|
||||
xenos::ColorRenderTargetFormat format;
|
||||
} color[4];
|
||||
// Depth/stencil attachment.
|
||||
struct {
|
||||
bool used;
|
||||
uint32_t edram_base;
|
||||
DepthRenderTargetFormat format;
|
||||
xenos::DepthRenderTargetFormat format;
|
||||
} depth_stencil;
|
||||
};
|
||||
|
||||
@@ -285,7 +285,7 @@ class RenderCache {
|
||||
bool dirty() const;
|
||||
|
||||
CachedTileView* FindTileView(uint32_t base, uint32_t pitch,
|
||||
MsaaSamples samples, bool color_or_depth,
|
||||
xenos::MsaaSamples samples, bool color_or_depth,
|
||||
uint32_t format);
|
||||
|
||||
// Begins a render pass targeting the state-specified framebuffer formats.
|
||||
@@ -311,23 +311,26 @@ class RenderCache {
|
||||
// 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, MsaaSamples num_samples,
|
||||
VkImage image, VkImageLayout image_layout,
|
||||
bool color_or_depth, uint32_t format, VkFilter filter,
|
||||
VkOffset3D offset, VkExtent3D extents);
|
||||
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,
|
||||
ColorRenderTargetFormat format, uint32_t pitch,
|
||||
uint32_t height, MsaaSamples num_samples, float* color);
|
||||
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,
|
||||
DepthRenderTargetFormat format, uint32_t pitch,
|
||||
uint32_t height, MsaaSamples num_samples,
|
||||
float depth, uint32_t stencil);
|
||||
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);
|
||||
|
||||
@@ -38,7 +38,7 @@ using xe::ui::vulkan::CheckResult;
|
||||
constexpr uint32_t kMaxTextureSamplers = 32;
|
||||
constexpr VkDeviceSize kStagingBufferSize = 64 * 1024 * 1024;
|
||||
|
||||
const char* get_dimension_name(Dimension dimension) {
|
||||
const char* get_dimension_name(xenos::DataDimension dimension) {
|
||||
static const char* names[] = {
|
||||
"1D",
|
||||
"2D",
|
||||
@@ -203,8 +203,8 @@ TextureCache::Texture* TextureCache::AllocateTexture(
|
||||
image_info.flags = 0;
|
||||
|
||||
switch (texture_info.dimension) {
|
||||
case Dimension::k1D:
|
||||
case Dimension::k2D:
|
||||
case xenos::DataDimension::k1D:
|
||||
case xenos::DataDimension::k2DOrStacked:
|
||||
if (!texture_info.is_stacked) {
|
||||
image_info.imageType = VK_IMAGE_TYPE_2D;
|
||||
} else {
|
||||
@@ -212,10 +212,10 @@ TextureCache::Texture* TextureCache::AllocateTexture(
|
||||
image_info.flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
|
||||
}
|
||||
break;
|
||||
case Dimension::k3D:
|
||||
case xenos::DataDimension::k3D:
|
||||
image_info.imageType = VK_IMAGE_TYPE_3D;
|
||||
break;
|
||||
case Dimension::kCube:
|
||||
case xenos::DataDimension::kCube:
|
||||
image_info.imageType = VK_IMAGE_TYPE_2D;
|
||||
image_info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
|
||||
is_cube = true;
|
||||
@@ -242,7 +242,7 @@ TextureCache::Texture* TextureCache::AllocateTexture(
|
||||
required_flags & ~props.optimalTilingFeatures)));
|
||||
}
|
||||
|
||||
if (texture_info.dimension != Dimension::kCube &&
|
||||
if (texture_info.dimension != xenos::DataDimension::kCube &&
|
||||
props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) {
|
||||
// Add color attachment usage if it's supported.
|
||||
image_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
@@ -502,8 +502,8 @@ TextureCache::Texture* TextureCache::DemandResolveTexture(
|
||||
}
|
||||
|
||||
VkFormatFeatureFlags required_flags = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
|
||||
if (texture_info.format == TextureFormat::k_24_8 ||
|
||||
texture_info.format == TextureFormat::k_24_8_FLOAT) {
|
||||
if (texture_info.format == xenos::TextureFormat::k_24_8 ||
|
||||
texture_info.format == xenos::TextureFormat::k_24_8_FLOAT) {
|
||||
required_flags |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
} else {
|
||||
required_flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
|
||||
@@ -639,18 +639,18 @@ TextureCache::TextureView* TextureCache::DemandView(Texture* texture,
|
||||
|
||||
bool is_cube = false;
|
||||
switch (texture->texture_info.dimension) {
|
||||
case Dimension::k1D:
|
||||
case Dimension::k2D:
|
||||
case xenos::DataDimension::k1D:
|
||||
case xenos::DataDimension::k2DOrStacked:
|
||||
if (!texture->texture_info.is_stacked) {
|
||||
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
} else {
|
||||
view_info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||
}
|
||||
break;
|
||||
case Dimension::k3D:
|
||||
case xenos::DataDimension::k3D:
|
||||
view_info.viewType = VK_IMAGE_VIEW_TYPE_3D;
|
||||
break;
|
||||
case Dimension::kCube:
|
||||
case xenos::DataDimension::kCube:
|
||||
view_info.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
|
||||
is_cube = true;
|
||||
break;
|
||||
@@ -739,14 +739,14 @@ TextureCache::Sampler* TextureCache::Demand(const SamplerInfo& sampler_info) {
|
||||
// Texture level filtering.
|
||||
VkSamplerMipmapMode mip_filter;
|
||||
switch (sampler_info.mip_filter) {
|
||||
case TextureFilter::kBaseMap:
|
||||
case xenos::TextureFilter::kBaseMap:
|
||||
// TODO(DrChat): ?
|
||||
mip_filter = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
break;
|
||||
case TextureFilter::kPoint:
|
||||
case xenos::TextureFilter::kPoint:
|
||||
mip_filter = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
break;
|
||||
case TextureFilter::kLinear:
|
||||
case xenos::TextureFilter::kLinear:
|
||||
mip_filter = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
break;
|
||||
default:
|
||||
@@ -756,10 +756,10 @@ TextureCache::Sampler* TextureCache::Demand(const SamplerInfo& sampler_info) {
|
||||
|
||||
VkFilter min_filter;
|
||||
switch (sampler_info.min_filter) {
|
||||
case TextureFilter::kPoint:
|
||||
case xenos::TextureFilter::kPoint:
|
||||
min_filter = VK_FILTER_NEAREST;
|
||||
break;
|
||||
case TextureFilter::kLinear:
|
||||
case xenos::TextureFilter::kLinear:
|
||||
min_filter = VK_FILTER_LINEAR;
|
||||
break;
|
||||
default:
|
||||
@@ -768,10 +768,10 @@ TextureCache::Sampler* TextureCache::Demand(const SamplerInfo& sampler_info) {
|
||||
}
|
||||
VkFilter mag_filter;
|
||||
switch (sampler_info.mag_filter) {
|
||||
case TextureFilter::kPoint:
|
||||
case xenos::TextureFilter::kPoint:
|
||||
mag_filter = VK_FILTER_NEAREST;
|
||||
break;
|
||||
case TextureFilter::kLinear:
|
||||
case xenos::TextureFilter::kLinear:
|
||||
mag_filter = VK_FILTER_LINEAR;
|
||||
break;
|
||||
default:
|
||||
@@ -803,22 +803,22 @@ TextureCache::Sampler* TextureCache::Demand(const SamplerInfo& sampler_info) {
|
||||
|
||||
float aniso = 0.f;
|
||||
switch (sampler_info.aniso_filter) {
|
||||
case AnisoFilter::kDisabled:
|
||||
case xenos::AnisoFilter::kDisabled:
|
||||
aniso = 1.0f;
|
||||
break;
|
||||
case AnisoFilter::kMax_1_1:
|
||||
case xenos::AnisoFilter::kMax_1_1:
|
||||
aniso = 1.0f;
|
||||
break;
|
||||
case AnisoFilter::kMax_2_1:
|
||||
case xenos::AnisoFilter::kMax_2_1:
|
||||
aniso = 2.0f;
|
||||
break;
|
||||
case AnisoFilter::kMax_4_1:
|
||||
case xenos::AnisoFilter::kMax_4_1:
|
||||
aniso = 4.0f;
|
||||
break;
|
||||
case AnisoFilter::kMax_8_1:
|
||||
case xenos::AnisoFilter::kMax_8_1:
|
||||
aniso = 8.0f;
|
||||
break;
|
||||
case AnisoFilter::kMax_16_1:
|
||||
case xenos::AnisoFilter::kMax_16_1:
|
||||
aniso = 16.0f;
|
||||
break;
|
||||
default:
|
||||
@@ -827,7 +827,8 @@ TextureCache::Sampler* TextureCache::Demand(const SamplerInfo& sampler_info) {
|
||||
}
|
||||
|
||||
sampler_create_info.anisotropyEnable =
|
||||
sampler_info.aniso_filter != AnisoFilter::kDisabled ? VK_TRUE : VK_FALSE;
|
||||
sampler_info.aniso_filter != xenos::AnisoFilter::kDisabled ? VK_TRUE
|
||||
: VK_FALSE;
|
||||
sampler_create_info.maxAnisotropy = aniso;
|
||||
|
||||
sampler_create_info.compareEnable = VK_FALSE;
|
||||
@@ -853,11 +854,12 @@ TextureCache::Sampler* TextureCache::Demand(const SamplerInfo& sampler_info) {
|
||||
return sampler;
|
||||
}
|
||||
|
||||
bool TextureFormatIsSimilar(TextureFormat left, TextureFormat right) {
|
||||
#define COMPARE_FORMAT(x, y) \
|
||||
if ((left == TextureFormat::x && right == TextureFormat::y) || \
|
||||
(left == TextureFormat::y && right == TextureFormat::x)) { \
|
||||
return true; \
|
||||
bool TextureFormatIsSimilar(xenos::TextureFormat left,
|
||||
xenos::TextureFormat right) {
|
||||
#define COMPARE_FORMAT(x, y) \
|
||||
if ((left == xenos::TextureFormat::x && right == xenos::TextureFormat::y) || \
|
||||
(left == xenos::TextureFormat::y && right == xenos::TextureFormat::x)) { \
|
||||
return true; \
|
||||
}
|
||||
|
||||
if (left == right) return true;
|
||||
@@ -913,7 +915,7 @@ TextureCache::Texture* TextureCache::Lookup(const TextureInfo& texture_info) {
|
||||
TextureCache::Texture* TextureCache::LookupAddress(uint32_t guest_address,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
TextureFormat format,
|
||||
xenos::TextureFormat format,
|
||||
VkOffset2D* out_offset) {
|
||||
for (auto it = textures_.begin(); it != textures_.end(); ++it) {
|
||||
const auto& texture_info = it->second->texture_info;
|
||||
@@ -924,7 +926,7 @@ TextureCache::Texture* TextureCache::LookupAddress(uint32_t guest_address,
|
||||
out_offset) {
|
||||
auto offset_bytes = guest_address - texture_info.memory.base_address;
|
||||
|
||||
if (texture_info.dimension == Dimension::k2D) {
|
||||
if (texture_info.dimension == xenos::DataDimension::k2DOrStacked) {
|
||||
out_offset->x = 0;
|
||||
out_offset->y = offset_bytes / texture_info.pitch;
|
||||
if (offset_bytes % texture_info.pitch != 0) {
|
||||
@@ -936,7 +938,7 @@ TextureCache::Texture* TextureCache::LookupAddress(uint32_t guest_address,
|
||||
}
|
||||
|
||||
if (texture_info.memory.base_address == guest_address &&
|
||||
texture_info.dimension == Dimension::k2D &&
|
||||
texture_info.dimension == xenos::DataDimension::k2DOrStacked &&
|
||||
texture_info.pitch == width && texture_info.height == height) {
|
||||
if (out_offset) {
|
||||
out_offset->x = 0;
|
||||
@@ -1000,7 +1002,7 @@ bool TextureCache::ConvertTexture(uint8_t* dest, VkBufferImageCopy* copy_region,
|
||||
|
||||
void* host_address = memory_->TranslatePhysical(address);
|
||||
|
||||
auto is_cube = src.dimension == Dimension::kCube;
|
||||
auto is_cube = src.dimension == xenos::DataDimension::kCube;
|
||||
auto src_extent = src.GetMipExtent(mip, true);
|
||||
auto dst_extent = GetMipExtent(src, mip);
|
||||
|
||||
@@ -1218,23 +1220,23 @@ bool TextureCache::UploadTexture(VkCommandBuffer command_buffer,
|
||||
return true;
|
||||
}
|
||||
|
||||
const FormatInfo* TextureCache::GetFormatInfo(TextureFormat format) {
|
||||
const FormatInfo* TextureCache::GetFormatInfo(xenos::TextureFormat format) {
|
||||
switch (format) {
|
||||
case TextureFormat::k_CTX1:
|
||||
return FormatInfo::Get(TextureFormat::k_8_8);
|
||||
case TextureFormat::k_DXT3A:
|
||||
return FormatInfo::Get(TextureFormat::k_DXT2_3);
|
||||
case xenos::TextureFormat::k_CTX1:
|
||||
return FormatInfo::Get(xenos::TextureFormat::k_8_8);
|
||||
case xenos::TextureFormat::k_DXT3A:
|
||||
return FormatInfo::Get(xenos::TextureFormat::k_DXT2_3);
|
||||
default:
|
||||
return FormatInfo::Get(format);
|
||||
}
|
||||
}
|
||||
|
||||
texture_conversion::CopyBlockCallback TextureCache::GetFormatCopyBlock(
|
||||
TextureFormat format) {
|
||||
xenos::TextureFormat format) {
|
||||
switch (format) {
|
||||
case TextureFormat::k_CTX1:
|
||||
case xenos::TextureFormat::k_CTX1:
|
||||
return texture_conversion::ConvertTexelCTX1ToR8G8;
|
||||
case TextureFormat::k_DXT3A:
|
||||
case xenos::TextureFormat::k_DXT3A:
|
||||
return texture_conversion::ConvertTexelDXT3AToDXT3;
|
||||
default:
|
||||
return texture_conversion::CopySwapBlock;
|
||||
|
||||
@@ -110,7 +110,7 @@ class TextureCache {
|
||||
// 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, TextureFormat format,
|
||||
uint32_t height, xenos::TextureFormat format,
|
||||
VkOffset2D* out_offset = nullptr);
|
||||
|
||||
TextureView* DemandView(Texture* texture, uint16_t swizzle);
|
||||
@@ -166,9 +166,9 @@ class TextureCache {
|
||||
bool ConvertTexture(uint8_t* dest, VkBufferImageCopy* copy_region,
|
||||
uint32_t mip, const TextureInfo& src);
|
||||
|
||||
static const FormatInfo* GetFormatInfo(TextureFormat format);
|
||||
static const FormatInfo* GetFormatInfo(xenos::TextureFormat format);
|
||||
static texture_conversion::CopyBlockCallback GetFormatCopyBlock(
|
||||
TextureFormat format);
|
||||
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,
|
||||
|
||||
@@ -589,7 +589,7 @@ void VulkanCommandProcessor::PerformSwap(uint32_t frontbuffer_ptr,
|
||||
current_batch_fence_ = nullptr;
|
||||
}
|
||||
|
||||
Shader* VulkanCommandProcessor::LoadShader(ShaderType shader_type,
|
||||
Shader* VulkanCommandProcessor::LoadShader(xenos::ShaderType shader_type,
|
||||
uint32_t guest_address,
|
||||
const uint32_t* host_address,
|
||||
uint32_t dword_count) {
|
||||
@@ -597,7 +597,7 @@ Shader* VulkanCommandProcessor::LoadShader(ShaderType shader_type,
|
||||
dword_count);
|
||||
}
|
||||
|
||||
bool VulkanCommandProcessor::IssueDraw(PrimitiveType primitive_type,
|
||||
bool VulkanCommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
|
||||
uint32_t index_count,
|
||||
IndexBufferInfo* index_buffer_info,
|
||||
bool major_mode_explicit) {
|
||||
@@ -783,16 +783,17 @@ bool VulkanCommandProcessor::PopulateIndexBuffer(
|
||||
assert_true(min_index == 0);
|
||||
assert_true(max_index == 0xFFFF || max_index == 0xFFFFFF);
|
||||
|
||||
assert_true(info.endianness == Endian::k8in16 ||
|
||||
info.endianness == Endian::k8in32);
|
||||
assert_true(info.endianness == xenos::Endian::k8in16 ||
|
||||
info.endianness == xenos::Endian::k8in32);
|
||||
|
||||
trace_writer_.WriteMemoryRead(info.guest_base, info.length);
|
||||
|
||||
// Upload (or get a cached copy of) the buffer.
|
||||
uint32_t source_addr = info.guest_base;
|
||||
uint32_t source_length =
|
||||
info.count * (info.format == IndexFormat::kInt32 ? sizeof(uint32_t)
|
||||
: sizeof(uint16_t));
|
||||
info.count * (info.format == xenos::IndexFormat::kInt32
|
||||
? sizeof(uint32_t)
|
||||
: sizeof(uint16_t));
|
||||
auto buffer_ref = buffer_cache_->UploadIndexBuffer(
|
||||
current_setup_buffer_, source_addr, source_length, info.format,
|
||||
current_batch_fence_);
|
||||
@@ -802,7 +803,7 @@ bool VulkanCommandProcessor::PopulateIndexBuffer(
|
||||
}
|
||||
|
||||
// Bind the buffer.
|
||||
VkIndexType index_type = info.format == IndexFormat::kInt32
|
||||
VkIndexType index_type = info.format == xenos::IndexFormat::kInt32
|
||||
? VK_INDEX_TYPE_UINT32
|
||||
: VK_INDEX_TYPE_UINT16;
|
||||
vkCmdBindIndexBuffer(command_buffer, buffer_ref.first, buffer_ref.second,
|
||||
@@ -926,7 +927,8 @@ bool VulkanCommandProcessor::IssueCopy() {
|
||||
// https://fossies.org/dox/MesaLib-10.3.5/fd2__gmem_8c_source.html
|
||||
uint32_t surface_info = regs[XE_GPU_REG_RB_SURFACE_INFO].u32;
|
||||
uint32_t surface_pitch = surface_info & 0x3FFF;
|
||||
auto surface_msaa = static_cast<MsaaSamples>((surface_info >> 16) & 0x3);
|
||||
auto surface_msaa =
|
||||
static_cast<xenos::MsaaSamples>((surface_info >> 16) & 0x3);
|
||||
|
||||
// TODO(benvanik): any way to scissor this? a200 has:
|
||||
// REG_A2XX_RB_COPY_DEST_OFFSET = A2XX_RB_COPY_DEST_OFFSET_X(tile->xoff) |
|
||||
@@ -969,7 +971,7 @@ bool VulkanCommandProcessor::IssueCopy() {
|
||||
break;
|
||||
}
|
||||
assert_true(fetch->type == xenos::FetchConstantType::kVertex);
|
||||
assert_true(fetch->endian == Endian::k8in32);
|
||||
assert_true(fetch->endian == xenos::Endian::k8in32);
|
||||
assert_true(fetch->size == 6);
|
||||
const uint8_t* vertex_addr = memory_->TranslatePhysical(fetch->address << 2);
|
||||
trace_writer_.WriteMemoryRead(fetch->address << 2, fetch->size * 4);
|
||||
@@ -1002,8 +1004,8 @@ bool VulkanCommandProcessor::IssueCopy() {
|
||||
|
||||
uint32_t color_edram_base = 0;
|
||||
uint32_t depth_edram_base = 0;
|
||||
ColorRenderTargetFormat color_format;
|
||||
DepthRenderTargetFormat depth_format;
|
||||
xenos::ColorRenderTargetFormat color_format;
|
||||
xenos::DepthRenderTargetFormat depth_format;
|
||||
if (is_color_source) {
|
||||
// Source from a color target.
|
||||
reg::RB_COLOR_INFO color_info[4] = {
|
||||
@@ -1027,10 +1029,10 @@ bool VulkanCommandProcessor::IssueCopy() {
|
||||
}
|
||||
}
|
||||
|
||||
Endian resolve_endian = Endian::k8in32;
|
||||
if (copy_regs->copy_dest_info.copy_dest_endian <= Endian128::k16in32) {
|
||||
xenos::Endian resolve_endian = xenos::Endian::k8in32;
|
||||
if (copy_regs->copy_dest_info.copy_dest_endian <= xenos::Endian128::k16in32) {
|
||||
resolve_endian =
|
||||
static_cast<Endian>(copy_regs->copy_dest_info.copy_dest_endian);
|
||||
static_cast<xenos::Endian>(copy_regs->copy_dest_info.copy_dest_endian);
|
||||
}
|
||||
|
||||
// Demand a resolve texture from the texture cache.
|
||||
|
||||
@@ -76,11 +76,11 @@ class VulkanCommandProcessor : public CommandProcessor {
|
||||
void PerformSwap(uint32_t frontbuffer_ptr, uint32_t frontbuffer_width,
|
||||
uint32_t frontbuffer_height) override;
|
||||
|
||||
Shader* LoadShader(ShaderType shader_type, uint32_t guest_address,
|
||||
Shader* LoadShader(xenos::ShaderType shader_type, uint32_t guest_address,
|
||||
const uint32_t* host_address,
|
||||
uint32_t dword_count) override;
|
||||
|
||||
bool IssueDraw(PrimitiveType primitive_type, uint32_t index_count,
|
||||
bool IssueDraw(xenos::PrimitiveType primitive_type, uint32_t index_count,
|
||||
IndexBufferInfo* index_buffer_info,
|
||||
bool major_mode_explicit) override;
|
||||
bool PopulateConstants(VkCommandBuffer command_buffer,
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace vulkan {
|
||||
using xe::ui::vulkan::CheckResult;
|
||||
|
||||
VulkanShader::VulkanShader(ui::vulkan::VulkanDevice* device,
|
||||
ShaderType shader_type, uint64_t data_hash,
|
||||
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) {}
|
||||
|
||||
@@ -50,9 +50,9 @@ bool VulkanShader::Prepare() {
|
||||
vkCreateShaderModule(*device_, &shader_info, nullptr, &shader_module_);
|
||||
CheckResult(status, "vkCreateShaderModule");
|
||||
|
||||
char typeChar = shader_type_ == ShaderType::kPixel
|
||||
char typeChar = shader_type_ == xenos::ShaderType::kPixel
|
||||
? 'p'
|
||||
: shader_type_ == ShaderType::kVertex ? 'v' : 'u';
|
||||
: 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()));
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace vulkan {
|
||||
|
||||
class VulkanShader : public Shader {
|
||||
public:
|
||||
VulkanShader(ui::vulkan::VulkanDevice* device, ShaderType shader_type,
|
||||
VulkanShader(ui::vulkan::VulkanDevice* device, xenos::ShaderType shader_type,
|
||||
uint64_t data_hash, const uint32_t* dword_ptr,
|
||||
uint32_t dword_count);
|
||||
~VulkanShader() override;
|
||||
|
||||
@@ -25,9 +25,9 @@ class VulkanTraceViewer : public TraceViewer {
|
||||
return std::unique_ptr<gpu::GraphicsSystem>(new VulkanGraphicsSystem());
|
||||
}
|
||||
|
||||
uintptr_t GetColorRenderTarget(uint32_t pitch, MsaaSamples samples,
|
||||
uint32_t base,
|
||||
ColorRenderTargetFormat format) override {
|
||||
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,
|
||||
@@ -35,9 +35,9 @@ class VulkanTraceViewer : public TraceViewer {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uintptr_t GetDepthRenderTarget(uint32_t pitch, MsaaSamples samples,
|
||||
uint32_t base,
|
||||
DepthRenderTargetFormat format) override {
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user