mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-30 22:49:53 +08:00
fix vulkan error from astrobot (#689)
* fix vulkan error from astrobot * a bit of a clean * a bit of a clean
This commit is contained in:
@@ -9271,6 +9271,27 @@ internal static unsafe class VulkanVideoPresenter
|
|||||||
!_guestImages.ContainsKey(texture.Address))
|
!_guestImages.ContainsKey(texture.Address))
|
||||||
{
|
{
|
||||||
var guestFormat = GetGuestTextureFormat(texture.Format, texture.NumberType);
|
var guestFormat = GetGuestTextureFormat(texture.Format, texture.NumberType);
|
||||||
|
|
||||||
|
var canonicalView = view;
|
||||||
|
if (texture.DstSelect != 0xFAC)
|
||||||
|
{
|
||||||
|
var identityViewInfo = new ImageViewCreateInfo
|
||||||
|
{
|
||||||
|
SType = StructureType.ImageViewCreateInfo,
|
||||||
|
Image = image,
|
||||||
|
ViewType = GetGuestTextureViewType(
|
||||||
|
texture.Type,
|
||||||
|
texture.ArrayedView),
|
||||||
|
Format = vkFormat,
|
||||||
|
Components = ToVkComponentMapping(0xFAC),
|
||||||
|
SubresourceRange = ColorSubresourceRange(layerCount: layers),
|
||||||
|
};
|
||||||
|
Check(
|
||||||
|
_vk.CreateImageView(_device, &identityViewInfo, null, out canonicalView),
|
||||||
|
"vkCreateImageView(texture identity)");
|
||||||
|
SetDebugName(ObjectType.ImageView, canonicalView.Handle, $"{debugName} identity view");
|
||||||
|
}
|
||||||
|
|
||||||
var guestImage = new GuestImageResource
|
var guestImage = new GuestImageResource
|
||||||
{
|
{
|
||||||
Address = texture.Address,
|
Address = texture.Address,
|
||||||
@@ -9286,7 +9307,7 @@ internal static unsafe class VulkanVideoPresenter
|
|||||||
Format = vkFormat,
|
Format = vkFormat,
|
||||||
Image = image,
|
Image = image,
|
||||||
Memory = imageMemory,
|
Memory = imageMemory,
|
||||||
View = view,
|
View = canonicalView,
|
||||||
InitialUploadPending = true,
|
InitialUploadPending = true,
|
||||||
IsCpuBacked = true,
|
IsCpuBacked = true,
|
||||||
CpuContentFingerprint = contentFingerprint,
|
CpuContentFingerprint = contentFingerprint,
|
||||||
@@ -11186,6 +11207,8 @@ internal static unsafe class VulkanVideoPresenter
|
|||||||
EnsureGuestSubmissionCapacity();
|
EnsureGuestSubmissionCapacity();
|
||||||
resources = CreateComputeDispatchResources(work);
|
resources = CreateComputeDispatchResources(work);
|
||||||
|
|
||||||
|
FlushBatchedGuestCommands();
|
||||||
|
|
||||||
var batchCount = Math.Max(
|
var batchCount = Math.Max(
|
||||||
1u,
|
1u,
|
||||||
(uint)Math.Ceiling(work.GroupCountZ / (double)MaxComputeZSlicesPerSubmission));
|
(uint)Math.Ceiling(work.GroupCountZ / (double)MaxComputeZSlicesPerSubmission));
|
||||||
@@ -14338,11 +14361,6 @@ internal static unsafe class VulkanVideoPresenter
|
|||||||
pendingGuestWork.Queue.Name,
|
pendingGuestWork.Queue.Name,
|
||||||
StringComparison.Ordinal))
|
StringComparison.Ordinal))
|
||||||
{
|
{
|
||||||
// A host command buffer must never contain commands from
|
|
||||||
// two independent guest queues: an ordered action fences
|
|
||||||
// only its own queue's predecessor submissions.
|
|
||||||
// Keep the previous work label so a device-lost on this
|
|
||||||
// flush still names the draws that filled the batch.
|
|
||||||
FlushBatchedGuestCommands();
|
FlushBatchedGuestCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14382,14 +14400,7 @@ internal static unsafe class VulkanVideoPresenter
|
|||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// A host-decoded movie only overrides which image gets
|
|
||||||
// presented (see the presentation selection below); the
|
|
||||||
// guest's own command stream keeps draining normally.
|
|
||||||
// Silently discarding these instead of executing them
|
|
||||||
// leaves guest-visible completion state (labels, buffers,
|
|
||||||
// job results) permanently unwritten, which desyncs the
|
|
||||||
// engine's own job system and previously crashed it
|
|
||||||
// shortly after the movie finished.
|
|
||||||
switch (work)
|
switch (work)
|
||||||
{
|
{
|
||||||
case VulkanOffscreenGuestDraw offscreenDraw:
|
case VulkanOffscreenGuestDraw offscreenDraw:
|
||||||
@@ -14711,6 +14722,8 @@ internal static unsafe class VulkanVideoPresenter
|
|||||||
$"[LOADER][ERROR] Vulkan VideoOut translated draw setup failed: {exception.Message}");
|
$"[LOADER][ERROR] Vulkan VideoOut translated draw setup failed: {exception.Message}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FlushBatchedGuestCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint imageIndex;
|
uint imageIndex;
|
||||||
@@ -15322,6 +15335,11 @@ internal static unsafe class VulkanVideoPresenter
|
|||||||
RecordGuestDepthForSampling(depth, shaderStage);
|
RecordGuestDepthForSampling(depth, shaderStage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!texture.IsStorage && texture.GuestImage is { } sampledGuestImage)
|
||||||
|
{
|
||||||
|
RecordGuestImageForSampling(sampledGuestImage, shaderStage);
|
||||||
|
}
|
||||||
|
|
||||||
if (!texture.NeedsUpload)
|
if (!texture.NeedsUpload)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@@ -15529,6 +15547,76 @@ internal static unsafe class VulkanVideoPresenter
|
|||||||
depth.Layout = ImageLayout.ShaderReadOnlyOptimal;
|
depth.Layout = ImageLayout.ShaderReadOnlyOptimal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void RecordGuestImageForSampling(
|
||||||
|
GuestImageResource guestImage,
|
||||||
|
PipelineStageFlags shaderStage)
|
||||||
|
{
|
||||||
|
if (guestImage.Initialized || guestImage.InitialUploadPending)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var range = ColorSubresourceRange(0, Math.Max(guestImage.MipLevels, 1));
|
||||||
|
var toTransfer = new ImageMemoryBarrier
|
||||||
|
{
|
||||||
|
SType = StructureType.ImageMemoryBarrier,
|
||||||
|
DstAccessMask = AccessFlags.TransferWriteBit,
|
||||||
|
OldLayout = ImageLayout.Undefined,
|
||||||
|
NewLayout = ImageLayout.TransferDstOptimal,
|
||||||
|
SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||||
|
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||||
|
Image = guestImage.Image,
|
||||||
|
SubresourceRange = range,
|
||||||
|
};
|
||||||
|
_vk.CmdPipelineBarrier(
|
||||||
|
_commandBuffer,
|
||||||
|
PipelineStageFlags.TopOfPipeBit,
|
||||||
|
PipelineStageFlags.TransferBit,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
1,
|
||||||
|
&toTransfer);
|
||||||
|
|
||||||
|
var clearValue = new ClearColorValue(0f, 0f, 0f, 0f);
|
||||||
|
_vk.CmdClearColorImage(
|
||||||
|
_commandBuffer,
|
||||||
|
guestImage.Image,
|
||||||
|
ImageLayout.TransferDstOptimal,
|
||||||
|
&clearValue,
|
||||||
|
1,
|
||||||
|
&range);
|
||||||
|
|
||||||
|
var toShaderRead = new ImageMemoryBarrier
|
||||||
|
{
|
||||||
|
SType = StructureType.ImageMemoryBarrier,
|
||||||
|
SrcAccessMask = AccessFlags.TransferWriteBit,
|
||||||
|
DstAccessMask = AccessFlags.ShaderReadBit,
|
||||||
|
OldLayout = ImageLayout.TransferDstOptimal,
|
||||||
|
NewLayout = ImageLayout.ShaderReadOnlyOptimal,
|
||||||
|
SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||||
|
DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
|
||||||
|
Image = guestImage.Image,
|
||||||
|
SubresourceRange = range,
|
||||||
|
};
|
||||||
|
_vk.CmdPipelineBarrier(
|
||||||
|
_commandBuffer,
|
||||||
|
PipelineStageFlags.TransferBit,
|
||||||
|
shaderStage,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
1,
|
||||||
|
&toShaderRead);
|
||||||
|
|
||||||
|
guestImage.Initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
private void RecordStandaloneGuestDepthClear(GuestDepthResource depth)
|
private void RecordStandaloneGuestDepthClear(GuestDepthResource depth)
|
||||||
{
|
{
|
||||||
var depthRange = new ImageSubresourceRange(
|
var depthRange = new ImageSubresourceRange(
|
||||||
|
|||||||
Reference in New Issue
Block a user