[Vulkan] Frontbuffer presentation
This commit is contained in:
parent
3fc7d8753c
commit
4b4205ba00
|
@ -1,101 +0,0 @@
|
||||||
// Generated with `xb buildshaders`.
|
|
||||||
#if 0
|
|
||||||
; SPIR-V
|
|
||||||
; Version: 1.0
|
|
||||||
; Generator: Khronos Glslang Reference Front End; 10
|
|
||||||
; Bound: 23240
|
|
||||||
; Schema: 0
|
|
||||||
OpCapability Shader
|
|
||||||
%1 = OpExtInstImport "GLSL.std.450"
|
|
||||||
OpMemoryModel Logical GLSL450
|
|
||||||
OpEntryPoint Vertex %5663 "main" %3877 %gl_VertexIndex %4930
|
|
||||||
OpDecorate %3877 Location 0
|
|
||||||
OpDecorate %gl_VertexIndex BuiltIn VertexIndex
|
|
||||||
OpMemberDecorate %_struct_1032 0 BuiltIn Position
|
|
||||||
OpMemberDecorate %_struct_1032 1 BuiltIn PointSize
|
|
||||||
OpDecorate %_struct_1032 Block
|
|
||||||
%void = OpTypeVoid
|
|
||||||
%1282 = OpTypeFunction %void
|
|
||||||
%float = OpTypeFloat 32
|
|
||||||
%v2float = OpTypeVector %float 2
|
|
||||||
%_ptr_Output_v2float = OpTypePointer Output %v2float
|
|
||||||
%3877 = OpVariable %_ptr_Output_v2float Output
|
|
||||||
%int = OpTypeInt 32 1
|
|
||||||
%_ptr_Input_int = OpTypePointer Input %int
|
|
||||||
%gl_VertexIndex = OpVariable %_ptr_Input_int Input
|
|
||||||
%uint = OpTypeInt 32 0
|
|
||||||
%uint_1 = OpConstant %uint 1
|
|
||||||
%v2uint = OpTypeVector %uint 2
|
|
||||||
%uint_2 = OpConstant %uint 2
|
|
||||||
%v4float = OpTypeVector %float 4
|
|
||||||
%_struct_1032 = OpTypeStruct %v4float %float
|
|
||||||
%_ptr_Output__struct_1032 = OpTypePointer Output %_struct_1032
|
|
||||||
%4930 = OpVariable %_ptr_Output__struct_1032 Output
|
|
||||||
%int_0 = OpConstant %int 0
|
|
||||||
%float_2 = OpConstant %float 2
|
|
||||||
%float_1 = OpConstant %float 1
|
|
||||||
%float_0 = OpConstant %float 0
|
|
||||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
|
||||||
%1849 = OpConstantComposite %v2uint %uint_2 %uint_2
|
|
||||||
%768 = OpConstantComposite %v2float %float_1 %float_1
|
|
||||||
%5663 = OpFunction %void None %1282
|
|
||||||
%6733 = OpLabel
|
|
||||||
%12420 = OpLoad %int %gl_VertexIndex
|
|
||||||
%12986 = OpBitcast %uint %12420
|
|
||||||
%21962 = OpShiftLeftLogical %int %12420 %uint_1
|
|
||||||
%19941 = OpBitcast %uint %21962
|
|
||||||
%15527 = OpCompositeConstruct %v2uint %12986 %19941
|
|
||||||
%7198 = OpBitwiseAnd %v2uint %15527 %1849
|
|
||||||
%12989 = OpConvertUToF %v2float %7198
|
|
||||||
OpStore %3877 %12989
|
|
||||||
%23239 = OpLoad %v2float %3877
|
|
||||||
%20253 = OpVectorTimesScalar %v2float %23239 %float_2
|
|
||||||
%23195 = OpFSub %v2float %20253 %768
|
|
||||||
%7674 = OpCompositeExtract %float %23195 0
|
|
||||||
%15569 = OpCompositeExtract %float %23195 1
|
|
||||||
%18260 = OpCompositeConstruct %v4float %7674 %15569 %float_0 %float_1
|
|
||||||
%12055 = OpAccessChain %_ptr_Output_v4float %4930 %int_0
|
|
||||||
OpStore %12055 %18260
|
|
||||||
OpReturn
|
|
||||||
OpFunctionEnd
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const uint32_t fullscreen_tc_vs[] = {
|
|
||||||
0x07230203, 0x00010000, 0x0008000A, 0x00005AC8, 0x00000000, 0x00020011,
|
|
||||||
0x00000001, 0x0006000B, 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E,
|
|
||||||
0x00000000, 0x0003000E, 0x00000000, 0x00000001, 0x0008000F, 0x00000000,
|
|
||||||
0x0000161F, 0x6E69616D, 0x00000000, 0x00000F25, 0x00001029, 0x00001342,
|
|
||||||
0x00040047, 0x00000F25, 0x0000001E, 0x00000000, 0x00040047, 0x00001029,
|
|
||||||
0x0000000B, 0x0000002A, 0x00050048, 0x00000408, 0x00000000, 0x0000000B,
|
|
||||||
0x00000000, 0x00050048, 0x00000408, 0x00000001, 0x0000000B, 0x00000001,
|
|
||||||
0x00030047, 0x00000408, 0x00000002, 0x00020013, 0x00000008, 0x00030021,
|
|
||||||
0x00000502, 0x00000008, 0x00030016, 0x0000000D, 0x00000020, 0x00040017,
|
|
||||||
0x00000013, 0x0000000D, 0x00000002, 0x00040020, 0x00000290, 0x00000003,
|
|
||||||
0x00000013, 0x0004003B, 0x00000290, 0x00000F25, 0x00000003, 0x00040015,
|
|
||||||
0x0000000C, 0x00000020, 0x00000001, 0x00040020, 0x00000289, 0x00000001,
|
|
||||||
0x0000000C, 0x0004003B, 0x00000289, 0x00001029, 0x00000001, 0x00040015,
|
|
||||||
0x0000000B, 0x00000020, 0x00000000, 0x0004002B, 0x0000000B, 0x00000A0D,
|
|
||||||
0x00000001, 0x00040017, 0x00000011, 0x0000000B, 0x00000002, 0x0004002B,
|
|
||||||
0x0000000B, 0x00000A10, 0x00000002, 0x00040017, 0x0000001D, 0x0000000D,
|
|
||||||
0x00000004, 0x0004001E, 0x00000408, 0x0000001D, 0x0000000D, 0x00040020,
|
|
||||||
0x00000685, 0x00000003, 0x00000408, 0x0004003B, 0x00000685, 0x00001342,
|
|
||||||
0x00000003, 0x0004002B, 0x0000000C, 0x00000A0B, 0x00000000, 0x0004002B,
|
|
||||||
0x0000000D, 0x00000018, 0x40000000, 0x0004002B, 0x0000000D, 0x0000008A,
|
|
||||||
0x3F800000, 0x0004002B, 0x0000000D, 0x00000A0C, 0x00000000, 0x00040020,
|
|
||||||
0x0000029A, 0x00000003, 0x0000001D, 0x0005002C, 0x00000011, 0x00000739,
|
|
||||||
0x00000A10, 0x00000A10, 0x0005002C, 0x00000013, 0x00000300, 0x0000008A,
|
|
||||||
0x0000008A, 0x00050036, 0x00000008, 0x0000161F, 0x00000000, 0x00000502,
|
|
||||||
0x000200F8, 0x00001A4D, 0x0004003D, 0x0000000C, 0x00003084, 0x00001029,
|
|
||||||
0x0004007C, 0x0000000B, 0x000032BA, 0x00003084, 0x000500C4, 0x0000000C,
|
|
||||||
0x000055CA, 0x00003084, 0x00000A0D, 0x0004007C, 0x0000000B, 0x00004DE5,
|
|
||||||
0x000055CA, 0x00050050, 0x00000011, 0x00003CA7, 0x000032BA, 0x00004DE5,
|
|
||||||
0x000500C7, 0x00000011, 0x00001C1E, 0x00003CA7, 0x00000739, 0x00040070,
|
|
||||||
0x00000013, 0x000032BD, 0x00001C1E, 0x0003003E, 0x00000F25, 0x000032BD,
|
|
||||||
0x0004003D, 0x00000013, 0x00005AC7, 0x00000F25, 0x0005008E, 0x00000013,
|
|
||||||
0x00004F1D, 0x00005AC7, 0x00000018, 0x00050083, 0x00000013, 0x00005A9B,
|
|
||||||
0x00004F1D, 0x00000300, 0x00050051, 0x0000000D, 0x00001DFA, 0x00005A9B,
|
|
||||||
0x00000000, 0x00050051, 0x0000000D, 0x00003CD1, 0x00005A9B, 0x00000001,
|
|
||||||
0x00070050, 0x0000001D, 0x00004754, 0x00001DFA, 0x00003CD1, 0x00000A0C,
|
|
||||||
0x0000008A, 0x00050041, 0x0000029A, 0x00002F17, 0x00001342, 0x00000A0B,
|
|
||||||
0x0003003E, 0x00002F17, 0x00004754, 0x000100FD, 0x00010038,
|
|
||||||
};
|
|
|
@ -1,58 +0,0 @@
|
||||||
// Generated with `xb buildshaders`.
|
|
||||||
#if 0
|
|
||||||
; SPIR-V
|
|
||||||
; Version: 1.0
|
|
||||||
; Generator: Khronos Glslang Reference Front End; 10
|
|
||||||
; Bound: 24988
|
|
||||||
; Schema: 0
|
|
||||||
OpCapability Shader
|
|
||||||
%1 = OpExtInstImport "GLSL.std.450"
|
|
||||||
OpMemoryModel Logical GLSL450
|
|
||||||
OpEntryPoint Fragment %5663 "main" %5120 %3877
|
|
||||||
OpExecutionMode %5663 OriginUpperLeft
|
|
||||||
OpDecorate %5120 RelaxedPrecision
|
|
||||||
OpDecorate %5120 Location 0
|
|
||||||
OpDecorate %3877 Location 0
|
|
||||||
%void = OpTypeVoid
|
|
||||||
%1282 = OpTypeFunction %void
|
|
||||||
%float = OpTypeFloat 32
|
|
||||||
%v4float = OpTypeVector %float 4
|
|
||||||
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
|
||||||
%5120 = OpVariable %_ptr_Output_v4float Output
|
|
||||||
%v2float = OpTypeVector %float 2
|
|
||||||
%_ptr_Input_v2float = OpTypePointer Input %v2float
|
|
||||||
%3877 = OpVariable %_ptr_Input_v2float Input
|
|
||||||
%float_0 = OpConstant %float 0
|
|
||||||
%float_1 = OpConstant %float 1
|
|
||||||
%5663 = OpFunction %void None %1282
|
|
||||||
%24987 = OpLabel
|
|
||||||
%17674 = OpLoad %v2float %3877
|
|
||||||
%21995 = OpCompositeExtract %float %17674 0
|
|
||||||
%23327 = OpCompositeExtract %float %17674 1
|
|
||||||
%22408 = OpCompositeConstruct %v4float %21995 %23327 %float_0 %float_1
|
|
||||||
OpStore %5120 %22408
|
|
||||||
OpReturn
|
|
||||||
OpFunctionEnd
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const uint32_t uv_ps[] = {
|
|
||||||
0x07230203, 0x00010000, 0x0008000A, 0x0000619C, 0x00000000, 0x00020011,
|
|
||||||
0x00000001, 0x0006000B, 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E,
|
|
||||||
0x00000000, 0x0003000E, 0x00000000, 0x00000001, 0x0007000F, 0x00000004,
|
|
||||||
0x0000161F, 0x6E69616D, 0x00000000, 0x00001400, 0x00000F25, 0x00030010,
|
|
||||||
0x0000161F, 0x00000007, 0x00030047, 0x00001400, 0x00000000, 0x00040047,
|
|
||||||
0x00001400, 0x0000001E, 0x00000000, 0x00040047, 0x00000F25, 0x0000001E,
|
|
||||||
0x00000000, 0x00020013, 0x00000008, 0x00030021, 0x00000502, 0x00000008,
|
|
||||||
0x00030016, 0x0000000D, 0x00000020, 0x00040017, 0x0000001D, 0x0000000D,
|
|
||||||
0x00000004, 0x00040020, 0x0000029A, 0x00000003, 0x0000001D, 0x0004003B,
|
|
||||||
0x0000029A, 0x00001400, 0x00000003, 0x00040017, 0x00000013, 0x0000000D,
|
|
||||||
0x00000002, 0x00040020, 0x00000290, 0x00000001, 0x00000013, 0x0004003B,
|
|
||||||
0x00000290, 0x00000F25, 0x00000001, 0x0004002B, 0x0000000D, 0x00000A0C,
|
|
||||||
0x00000000, 0x0004002B, 0x0000000D, 0x0000008A, 0x3F800000, 0x00050036,
|
|
||||||
0x00000008, 0x0000161F, 0x00000000, 0x00000502, 0x000200F8, 0x0000619B,
|
|
||||||
0x0004003D, 0x00000013, 0x0000450A, 0x00000F25, 0x00050051, 0x0000000D,
|
|
||||||
0x000055EB, 0x0000450A, 0x00000000, 0x00050051, 0x0000000D, 0x00005B1F,
|
|
||||||
0x0000450A, 0x00000001, 0x00070050, 0x0000001D, 0x00005788, 0x000055EB,
|
|
||||||
0x00005B1F, 0x00000A0C, 0x0000008A, 0x0003003E, 0x00001400, 0x00005788,
|
|
||||||
0x000100FD, 0x00010038,
|
|
||||||
};
|
|
|
@ -1,10 +0,0 @@
|
||||||
#version 310 es
|
|
||||||
|
|
||||||
// A triangle covering the whole viewport.
|
|
||||||
|
|
||||||
layout(location = 0) out vec2 xe_var_texcoord;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
xe_var_texcoord = vec2(uvec2(gl_VertexIndex, gl_VertexIndex << 1u) & 2u);
|
|
||||||
gl_Position = vec4(xe_var_texcoord * 2.0 - 1.0, 0.0, 1.0);
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
#version 310 es
|
|
||||||
precision highp float;
|
|
||||||
|
|
||||||
layout(location = 0) in vec2 xe_var_texcoord;
|
|
||||||
|
|
||||||
layout(location = 0) out lowp vec4 xe_frag_color;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
xe_frag_color = vec4(xe_var_texcoord, 0.0, 1.0);
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
|
@ -265,6 +265,9 @@ class VulkanCommandProcessor : public CommandProcessor {
|
||||||
|
|
||||||
void WriteRegister(uint32_t index, uint32_t value) override;
|
void WriteRegister(uint32_t index, uint32_t value) override;
|
||||||
|
|
||||||
|
void OnGammaRamp256EntryTableValueWritten() override;
|
||||||
|
void OnGammaRampPWLValueWritten() override;
|
||||||
|
|
||||||
void IssueSwap(uint32_t frontbuffer_ptr, uint32_t frontbuffer_width,
|
void IssueSwap(uint32_t frontbuffer_ptr, uint32_t frontbuffer_width,
|
||||||
uint32_t frontbuffer_height) override;
|
uint32_t frontbuffer_height) override;
|
||||||
|
|
||||||
|
@ -398,6 +401,21 @@ class VulkanCommandProcessor : public CommandProcessor {
|
||||||
VkDescriptorSet set;
|
VkDescriptorSet set;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SwapApplyGammaDescriptorSet : uint32_t {
|
||||||
|
kSwapApplyGammaDescriptorSetRamp,
|
||||||
|
kSwapApplyGammaDescriptorSetSource,
|
||||||
|
|
||||||
|
kSwapApplyGammaDescriptorSetCount,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Framebuffer for the current presenter's guest output image revision, and
|
||||||
|
// its usage tracking.
|
||||||
|
struct SwapFramebuffer {
|
||||||
|
VkFramebuffer framebuffer = VK_NULL_HANDLE;
|
||||||
|
uint64_t version = UINT64_MAX;
|
||||||
|
uint64_t last_submission = 0;
|
||||||
|
};
|
||||||
|
|
||||||
// BeginSubmission and EndSubmission may be called at any time. If there's an
|
// BeginSubmission and EndSubmission may be called at any time. If there's an
|
||||||
// open non-frame submission, BeginSubmission(true) will promote it to a
|
// open non-frame submission, BeginSubmission(true) will promote it to a
|
||||||
// frame. EndSubmission(true) will close the frame no matter whether the
|
// frame. EndSubmission(true) will close the frame no matter whether the
|
||||||
|
@ -554,24 +572,55 @@ class VulkanCommandProcessor : public CommandProcessor {
|
||||||
VkDescriptorPool shared_memory_and_edram_descriptor_pool_ = VK_NULL_HANDLE;
|
VkDescriptorPool shared_memory_and_edram_descriptor_pool_ = VK_NULL_HANDLE;
|
||||||
VkDescriptorSet shared_memory_and_edram_descriptor_set_;
|
VkDescriptorSet shared_memory_and_edram_descriptor_set_;
|
||||||
|
|
||||||
|
// Bytes 0x0...0x3FF - 256-entry gamma ramp table with B10G10R10X2 data (read
|
||||||
|
// as R10G10B10X2 with swizzle).
|
||||||
|
// Bytes 0x400...0x9FF - 128-entry PWL R16G16 gamma ramp (R - base, G - delta,
|
||||||
|
// low 6 bits of each are zero, 3 elements per entry).
|
||||||
|
// kMaxFramesInFlight pairs of gamma ramps if in host-visible memory and
|
||||||
|
// uploaded directly, one otherwise.
|
||||||
|
VkDeviceMemory gamma_ramp_buffer_memory_ = VK_NULL_HANDLE;
|
||||||
|
VkBuffer gamma_ramp_buffer_ = VK_NULL_HANDLE;
|
||||||
|
// kMaxFramesInFlight pairs, only when the gamma ramp buffer is not
|
||||||
|
// host-visible.
|
||||||
|
VkDeviceMemory gamma_ramp_upload_buffer_memory_ = VK_NULL_HANDLE;
|
||||||
|
VkBuffer gamma_ramp_upload_buffer_ = VK_NULL_HANDLE;
|
||||||
|
VkDeviceSize gamma_ramp_upload_memory_size_;
|
||||||
|
uint32_t gamma_ramp_upload_memory_type_;
|
||||||
|
// Mapping of either gamma_ramp_buffer_memory_ (if it's host-visible) or
|
||||||
|
// gamma_ramp_upload_buffer_memory_ (otherwise).
|
||||||
|
void* gamma_ramp_upload_mapping_;
|
||||||
|
std::array<VkBufferView, 2 * kMaxFramesInFlight> gamma_ramp_buffer_views_{};
|
||||||
|
// UINT32_MAX if outdated.
|
||||||
|
uint32_t gamma_ramp_256_entry_table_current_frame_ = UINT32_MAX;
|
||||||
|
uint32_t gamma_ramp_pwl_current_frame_ = UINT32_MAX;
|
||||||
|
|
||||||
|
VkDescriptorSetLayout swap_descriptor_set_layout_sampled_image_ =
|
||||||
|
VK_NULL_HANDLE;
|
||||||
|
VkDescriptorSetLayout swap_descriptor_set_layout_uniform_texel_buffer_ =
|
||||||
|
VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
// Descriptor pool for allocating descriptors needed for presentation, such as
|
||||||
|
// the destination images and the gamma ramps.
|
||||||
|
VkDescriptorPool swap_descriptor_pool_ = VK_NULL_HANDLE;
|
||||||
|
// Interleaved 256-entry table and PWL texel buffer descriptors.
|
||||||
|
// kMaxFramesInFlight pairs of gamma ramps if in host-visible memory and
|
||||||
|
// uploaded directly, one otherwise.
|
||||||
|
std::array<VkDescriptorSet, 2 * kMaxFramesInFlight>
|
||||||
|
swap_descriptors_gamma_ramp_;
|
||||||
|
// Sampled images.
|
||||||
|
std::array<VkDescriptorSet, kMaxFramesInFlight> swap_descriptors_source_;
|
||||||
|
|
||||||
|
VkPipelineLayout swap_apply_gamma_pipeline_layout_ = VK_NULL_HANDLE;
|
||||||
// Has no dependencies on specific pipeline stages on both ends to simplify
|
// Has no dependencies on specific pipeline stages on both ends to simplify
|
||||||
// use in different scenarios with different pipelines - use explicit barriers
|
// use in different scenarios with different pipelines - use explicit barriers
|
||||||
// for synchronization. Drawing to VK_FORMAT_R8G8B8A8_SRGB.
|
// for synchronization.
|
||||||
VkRenderPass swap_render_pass_ = VK_NULL_HANDLE;
|
VkRenderPass swap_apply_gamma_render_pass_ = VK_NULL_HANDLE;
|
||||||
VkPipelineLayout swap_pipeline_layout_ = VK_NULL_HANDLE;
|
VkPipeline swap_apply_gamma_256_entry_table_pipeline_ = VK_NULL_HANDLE;
|
||||||
VkPipeline swap_pipeline_ = VK_NULL_HANDLE;
|
VkPipeline swap_apply_gamma_pwl_pipeline_ = VK_NULL_HANDLE;
|
||||||
|
|
||||||
// Framebuffer for the current presenter's guest output image revision, and
|
|
||||||
// its usage tracking.
|
|
||||||
struct SwapFramebuffer {
|
|
||||||
VkFramebuffer framebuffer = VK_NULL_HANDLE;
|
|
||||||
uint64_t version = UINT64_MAX;
|
|
||||||
uint64_t last_submission = 0;
|
|
||||||
};
|
|
||||||
std::array<SwapFramebuffer,
|
std::array<SwapFramebuffer,
|
||||||
ui::vulkan::VulkanPresenter::kMaxActiveGuestOutputImageVersions>
|
ui::vulkan::VulkanPresenter::kMaxActiveGuestOutputImageVersions>
|
||||||
swap_framebuffers_;
|
swap_framebuffers_;
|
||||||
std::deque<std::pair<uint64_t, VkFramebuffer>> swap_framebuffers_outdated_;
|
|
||||||
|
|
||||||
// Pending pipeline barriers.
|
// Pending pipeline barriers.
|
||||||
std::vector<VkBufferMemoryBarrier> pending_barriers_buffer_memory_barriers_;
|
std::vector<VkBufferMemoryBarrier> pending_barriers_buffer_memory_barriers_;
|
||||||
|
|
|
@ -589,6 +589,59 @@ VkImageView VulkanTextureCache::GetActiveBindingOrNullImageView(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkImageView VulkanTextureCache::RequestSwapTexture(
|
||||||
|
uint32_t& width_scaled_out, uint32_t& height_scaled_out,
|
||||||
|
xenos::TextureFormat& format_out) {
|
||||||
|
const auto& regs = register_file();
|
||||||
|
const auto& fetch = regs.Get<xenos::xe_gpu_texture_fetch_t>(
|
||||||
|
XE_GPU_REG_SHADER_CONSTANT_FETCH_00_0);
|
||||||
|
TextureKey key;
|
||||||
|
BindingInfoFromFetchConstant(fetch, key, nullptr);
|
||||||
|
if (!key.is_valid || key.base_page == 0 ||
|
||||||
|
key.dimension != xenos::DataDimension::k2DOrStacked) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
VulkanTexture* texture =
|
||||||
|
static_cast<VulkanTexture*>(FindOrCreateTexture(key));
|
||||||
|
if (!texture) {
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
VkImageView texture_view = texture->GetView(
|
||||||
|
false, GuestToHostSwizzle(fetch.swizzle, GetHostFormatSwizzle(key)),
|
||||||
|
false);
|
||||||
|
if (texture_view == VK_NULL_HANDLE) {
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
if (!LoadTextureData(*texture)) {
|
||||||
|
return VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
texture->MarkAsUsed();
|
||||||
|
VulkanTexture::Usage old_usage =
|
||||||
|
texture->SetUsage(VulkanTexture::Usage::kSwapSampled);
|
||||||
|
if (old_usage != VulkanTexture::Usage::kSwapSampled) {
|
||||||
|
VkPipelineStageFlags src_stage_mask, dst_stage_mask;
|
||||||
|
VkAccessFlags src_access_mask, dst_access_mask;
|
||||||
|
VkImageLayout old_layout, new_layout;
|
||||||
|
GetTextureUsageMasks(old_usage, src_stage_mask, src_access_mask,
|
||||||
|
old_layout);
|
||||||
|
GetTextureUsageMasks(VulkanTexture::Usage::kSwapSampled, dst_stage_mask,
|
||||||
|
dst_access_mask, new_layout);
|
||||||
|
command_processor_.PushImageMemoryBarrier(
|
||||||
|
texture->image(), ui::vulkan::util::InitializeSubresourceRange(),
|
||||||
|
src_stage_mask, dst_stage_mask, src_access_mask, dst_access_mask,
|
||||||
|
old_layout, new_layout);
|
||||||
|
}
|
||||||
|
// Only texture->key, not the result of BindingInfoFromFetchConstant, contains
|
||||||
|
// whether the texture is scaled.
|
||||||
|
key = texture->key();
|
||||||
|
width_scaled_out =
|
||||||
|
key.GetWidth() * (key.scaled_resolve ? draw_resolution_scale_x() : 1);
|
||||||
|
height_scaled_out =
|
||||||
|
key.GetHeight() * (key.scaled_resolve ? draw_resolution_scale_y() : 1);
|
||||||
|
format_out = key.format;
|
||||||
|
return texture_view;
|
||||||
|
}
|
||||||
|
|
||||||
bool VulkanTextureCache::IsSignedVersionSeparateForFormat(
|
bool VulkanTextureCache::IsSignedVersionSeparateForFormat(
|
||||||
TextureKey key) const {
|
TextureKey key) const {
|
||||||
const HostFormatPair& host_format_pair = GetHostFormatPair(key);
|
const HostFormatPair& host_format_pair = GetHostFormatPair(key);
|
||||||
|
@ -1263,7 +1316,14 @@ VulkanTextureCache::VulkanTexture::~VulkanTexture() {
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageView VulkanTextureCache::VulkanTexture::GetView(bool is_signed,
|
VkImageView VulkanTextureCache::VulkanTexture::GetView(bool is_signed,
|
||||||
uint32_t host_swizzle) {
|
uint32_t host_swizzle,
|
||||||
|
bool is_array) {
|
||||||
|
xenos::DataDimension dimension = key().dimension;
|
||||||
|
if (dimension == xenos::DataDimension::k3D ||
|
||||||
|
dimension == xenos::DataDimension::kCube) {
|
||||||
|
is_array = false;
|
||||||
|
}
|
||||||
|
|
||||||
const VulkanTextureCache& vulkan_texture_cache =
|
const VulkanTextureCache& vulkan_texture_cache =
|
||||||
static_cast<const VulkanTextureCache&>(texture_cache());
|
static_cast<const VulkanTextureCache&>(texture_cache());
|
||||||
|
|
||||||
|
@ -1297,6 +1357,8 @@ VkImageView VulkanTextureCache::VulkanTexture::GetView(bool is_signed,
|
||||||
}
|
}
|
||||||
view_key.host_swizzle = host_swizzle;
|
view_key.host_swizzle = host_swizzle;
|
||||||
|
|
||||||
|
view_key.is_array = uint32_t(is_array);
|
||||||
|
|
||||||
// Try to find an existing view.
|
// Try to find an existing view.
|
||||||
auto it = views_.find(view_key);
|
auto it = views_.find(view_key);
|
||||||
if (it != views_.end()) {
|
if (it != views_.end()) {
|
||||||
|
@ -1311,17 +1373,6 @@ VkImageView VulkanTextureCache::VulkanTexture::GetView(bool is_signed,
|
||||||
view_create_info.pNext = nullptr;
|
view_create_info.pNext = nullptr;
|
||||||
view_create_info.flags = 0;
|
view_create_info.flags = 0;
|
||||||
view_create_info.image = image();
|
view_create_info.image = image();
|
||||||
switch (key().dimension) {
|
|
||||||
case xenos::DataDimension::k3D:
|
|
||||||
view_create_info.viewType = VK_IMAGE_VIEW_TYPE_3D;
|
|
||||||
break;
|
|
||||||
case xenos::DataDimension::kCube:
|
|
||||||
view_create_info.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
view_create_info.format = format;
|
view_create_info.format = format;
|
||||||
view_create_info.components.r = GetComponentSwizzle(host_swizzle, 0);
|
view_create_info.components.r = GetComponentSwizzle(host_swizzle, 0);
|
||||||
view_create_info.components.g = GetComponentSwizzle(host_swizzle, 1);
|
view_create_info.components.g = GetComponentSwizzle(host_swizzle, 1);
|
||||||
|
@ -1329,6 +1380,22 @@ VkImageView VulkanTextureCache::VulkanTexture::GetView(bool is_signed,
|
||||||
view_create_info.components.a = GetComponentSwizzle(host_swizzle, 3);
|
view_create_info.components.a = GetComponentSwizzle(host_swizzle, 3);
|
||||||
view_create_info.subresourceRange =
|
view_create_info.subresourceRange =
|
||||||
ui::vulkan::util::InitializeSubresourceRange();
|
ui::vulkan::util::InitializeSubresourceRange();
|
||||||
|
switch (dimension) {
|
||||||
|
case xenos::DataDimension::k3D:
|
||||||
|
view_create_info.viewType = VK_IMAGE_VIEW_TYPE_3D;
|
||||||
|
break;
|
||||||
|
case xenos::DataDimension::kCube:
|
||||||
|
view_create_info.viewType = VK_IMAGE_VIEW_TYPE_CUBE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (is_array) {
|
||||||
|
view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||||
|
} else {
|
||||||
|
view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
|
view_create_info.subresourceRange.layerCount = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
VkImageView view;
|
VkImageView view;
|
||||||
if (dfn.vkCreateImageView(device, &view_create_info, nullptr, &view) !=
|
if (dfn.vkCreateImageView(device, &view_create_info, nullptr, &view) !=
|
||||||
VK_SUCCESS) {
|
VK_SUCCESS) {
|
||||||
|
@ -2248,9 +2315,10 @@ void VulkanTextureCache::GetTextureUsageMasks(VulkanTexture::Usage usage,
|
||||||
layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
break;
|
break;
|
||||||
case VulkanTexture::Usage::kSwapSampled:
|
case VulkanTexture::Usage::kSwapSampled:
|
||||||
// The swap texture is likely to be used only for the presentation compute
|
// The swap texture is likely to be used only for the presentation
|
||||||
// shader, and not during emulation, where it'd be used in other stages.
|
// fragment shader, and not during emulation, where it'd be used in other
|
||||||
stage_mask = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
// stages.
|
||||||
|
stage_mask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
|
||||||
access_mask = VK_ACCESS_SHADER_READ_BIT;
|
access_mask = VK_ACCESS_SHADER_READ_BIT;
|
||||||
layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -60,6 +60,13 @@ class VulkanTextureCache final : public TextureCache {
|
||||||
xenos::FetchOpDimension dimension,
|
xenos::FetchOpDimension dimension,
|
||||||
bool is_signed) const;
|
bool is_signed) const;
|
||||||
|
|
||||||
|
// Returns the 2D view of the front buffer texture (for fragment shader
|
||||||
|
// reading - the barrier will be pushed in the command processor if needed),
|
||||||
|
// or VK_NULL_HANDLE in case of failure. May call LoadTextureData.
|
||||||
|
VkImageView RequestSwapTexture(uint32_t& width_scaled_out,
|
||||||
|
uint32_t& height_scaled_out,
|
||||||
|
xenos::TextureFormat& format_out);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool IsSignedVersionSeparateForFormat(TextureKey key) const override;
|
bool IsSignedVersionSeparateForFormat(TextureKey key) const override;
|
||||||
uint32_t GetHostFormatSwizzle(TextureKey key) const override;
|
uint32_t GetHostFormatSwizzle(TextureKey key) const override;
|
||||||
|
@ -136,7 +143,8 @@ class VulkanTextureCache final : public TextureCache {
|
||||||
return old_usage;
|
return old_usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageView GetView(bool is_signed, uint32_t host_swizzle);
|
VkImageView GetView(bool is_signed, uint32_t host_swizzle,
|
||||||
|
bool is_array = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
union ViewKey {
|
union ViewKey {
|
||||||
|
@ -144,6 +152,7 @@ class VulkanTextureCache final : public TextureCache {
|
||||||
struct {
|
struct {
|
||||||
uint32_t is_signed_separate_view : 1;
|
uint32_t is_signed_separate_view : 1;
|
||||||
uint32_t host_swizzle : 12;
|
uint32_t host_swizzle : 12;
|
||||||
|
uint32_t is_array : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
ViewKey() : key(0) { static_assert_size(*this, sizeof(key)); }
|
ViewKey() : key(0) { static_assert_size(*this, sizeof(key)); }
|
||||||
|
|
|
@ -29,6 +29,7 @@ XE_UI_VULKAN_FUNCTION(vkCmdSetStencilReference)
|
||||||
XE_UI_VULKAN_FUNCTION(vkCmdSetStencilWriteMask)
|
XE_UI_VULKAN_FUNCTION(vkCmdSetStencilWriteMask)
|
||||||
XE_UI_VULKAN_FUNCTION(vkCmdSetViewport)
|
XE_UI_VULKAN_FUNCTION(vkCmdSetViewport)
|
||||||
XE_UI_VULKAN_FUNCTION(vkCreateBuffer)
|
XE_UI_VULKAN_FUNCTION(vkCreateBuffer)
|
||||||
|
XE_UI_VULKAN_FUNCTION(vkCreateBufferView)
|
||||||
XE_UI_VULKAN_FUNCTION(vkCreateCommandPool)
|
XE_UI_VULKAN_FUNCTION(vkCreateCommandPool)
|
||||||
XE_UI_VULKAN_FUNCTION(vkCreateComputePipelines)
|
XE_UI_VULKAN_FUNCTION(vkCreateComputePipelines)
|
||||||
XE_UI_VULKAN_FUNCTION(vkCreateDescriptorPool)
|
XE_UI_VULKAN_FUNCTION(vkCreateDescriptorPool)
|
||||||
|
@ -44,6 +45,7 @@ XE_UI_VULKAN_FUNCTION(vkCreateSampler)
|
||||||
XE_UI_VULKAN_FUNCTION(vkCreateSemaphore)
|
XE_UI_VULKAN_FUNCTION(vkCreateSemaphore)
|
||||||
XE_UI_VULKAN_FUNCTION(vkCreateShaderModule)
|
XE_UI_VULKAN_FUNCTION(vkCreateShaderModule)
|
||||||
XE_UI_VULKAN_FUNCTION(vkDestroyBuffer)
|
XE_UI_VULKAN_FUNCTION(vkDestroyBuffer)
|
||||||
|
XE_UI_VULKAN_FUNCTION(vkDestroyBufferView)
|
||||||
XE_UI_VULKAN_FUNCTION(vkDestroyCommandPool)
|
XE_UI_VULKAN_FUNCTION(vkDestroyCommandPool)
|
||||||
XE_UI_VULKAN_FUNCTION(vkDestroyDescriptorPool)
|
XE_UI_VULKAN_FUNCTION(vkDestroyDescriptorPool)
|
||||||
XE_UI_VULKAN_FUNCTION(vkDestroyDescriptorSetLayout)
|
XE_UI_VULKAN_FUNCTION(vkDestroyDescriptorSetLayout)
|
||||||
|
|
Loading…
Reference in New Issue