mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 21:11:39 +00:00
- implement RenderTextureView
This commit is contained in:
parent
d78cb959a7
commit
5d2917bb4f
4 changed files with 102 additions and 32 deletions
|
@ -269,13 +269,14 @@ sector_t *VulkanFrameBuffer::RenderView(player_t *player)
|
||||||
screen->mLights->Clear();
|
screen->mLights->Clear();
|
||||||
screen->mViewpoints->Clear();
|
screen->mViewpoints->Clear();
|
||||||
|
|
||||||
#if 0
|
|
||||||
// NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below.
|
// NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below.
|
||||||
bool saved_niv = NoInterpolateView;
|
bool saved_niv = NoInterpolateView;
|
||||||
NoInterpolateView = false;
|
NoInterpolateView = false;
|
||||||
|
|
||||||
// Shader start time does not need to be handled per level. Just use the one from the camera to render from.
|
// Shader start time does not need to be handled per level. Just use the one from the camera to render from.
|
||||||
|
#if 0
|
||||||
GetRenderState()->CheckTimer(player->camera->Level->ShaderStartTime);
|
GetRenderState()->CheckTimer(player->camera->Level->ShaderStartTime);
|
||||||
|
#endif
|
||||||
// prepare all camera textures that have been used in the last frame.
|
// prepare all camera textures that have been used in the last frame.
|
||||||
// This must be done for all levels, not just the primary one!
|
// This must be done for all levels, not just the primary one!
|
||||||
for (auto Level : AllLevels())
|
for (auto Level : AllLevels())
|
||||||
|
@ -286,7 +287,6 @@ sector_t *VulkanFrameBuffer::RenderView(player_t *player)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
NoInterpolateView = saved_niv;
|
NoInterpolateView = saved_niv;
|
||||||
#endif
|
|
||||||
|
|
||||||
// now render the main view
|
// now render the main view
|
||||||
float fovratio;
|
float fovratio;
|
||||||
|
@ -389,6 +389,45 @@ sector_t *VulkanFrameBuffer::RenderViewpoint(FRenderViewpoint &mainvp, AActor *
|
||||||
return mainvp.sector;
|
return mainvp.sector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VulkanFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV)
|
||||||
|
{
|
||||||
|
// This doesn't need to clear the fake flat cache. It can be shared between camera textures and the main view of a scene.
|
||||||
|
FMaterial *mat = FMaterial::ValidateTexture(tex, false);
|
||||||
|
auto BaseLayer = static_cast<VkHardwareTexture*>(mat->GetLayer(0, 0));
|
||||||
|
|
||||||
|
int width = mat->TextureWidth();
|
||||||
|
int height = mat->TextureHeight();
|
||||||
|
VulkanImage *image = BaseLayer->GetImage(tex, 0, 0);
|
||||||
|
VulkanImageView *view = BaseLayer->GetImageView(tex, 0, 0);
|
||||||
|
|
||||||
|
mRenderState->EndRenderPass();
|
||||||
|
auto cmdbuffer = GetDrawCommands();
|
||||||
|
|
||||||
|
PipelineBarrier barrier0;
|
||||||
|
barrier0.addImage(image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
|
||||||
|
barrier0.execute(cmdbuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
||||||
|
|
||||||
|
mRenderState->SetRenderTarget(view, image->width, image->height, VK_SAMPLE_COUNT_1_BIT);
|
||||||
|
|
||||||
|
IntRect bounds;
|
||||||
|
bounds.left = bounds.top = 0;
|
||||||
|
bounds.width = MIN(mat->GetWidth(), image->width);
|
||||||
|
bounds.height = MIN(mat->GetHeight(), image->height);
|
||||||
|
|
||||||
|
FRenderViewpoint texvp;
|
||||||
|
RenderViewpoint(texvp, Viewpoint, &bounds, FOV, (float)width / height, (float)width / height, false, false);
|
||||||
|
|
||||||
|
mRenderState->EndRenderPass();
|
||||||
|
|
||||||
|
PipelineBarrier barrier1;
|
||||||
|
barrier1.addImage(image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
|
||||||
|
barrier1.execute(cmdbuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
|
|
||||||
|
mRenderState->SetRenderTarget(GetBuffers()->SceneColorView.get(), GetBuffers()->GetWidth(), GetBuffers()->GetHeight(), GetBuffers()->GetSceneSamples());
|
||||||
|
|
||||||
|
tex->SetUpdated(true);
|
||||||
|
}
|
||||||
|
|
||||||
void VulkanFrameBuffer::DrawScene(HWDrawInfo *di, int drawmode)
|
void VulkanFrameBuffer::DrawScene(HWDrawInfo *di, int drawmode)
|
||||||
{
|
{
|
||||||
// To do: this is virtually identical to FGLRenderer::DrawScene and should be merged.
|
// To do: this is virtually identical to FGLRenderer::DrawScene and should be merged.
|
||||||
|
|
|
@ -80,6 +80,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sector_t *RenderViewpoint(FRenderViewpoint &mainvp, AActor * camera, IntRect * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen);
|
sector_t *RenderViewpoint(FRenderViewpoint &mainvp, AActor * camera, IntRect * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen);
|
||||||
|
void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV);
|
||||||
void DrawScene(HWDrawInfo *di, int drawmode);
|
void DrawScene(HWDrawInfo *di, int drawmode);
|
||||||
void PrintStartupLog();
|
void PrintStartupLog();
|
||||||
void CreateFanToTrisIndexBuffer();
|
void CreateFanToTrisIndexBuffer();
|
||||||
|
@ -98,8 +99,6 @@ private:
|
||||||
|
|
||||||
VkRenderBuffers *mActiveRenderBuffers = nullptr;
|
VkRenderBuffers *mActiveRenderBuffers = nullptr;
|
||||||
|
|
||||||
int camtexcount = 0;
|
|
||||||
|
|
||||||
int lastSwapWidth = 0;
|
int lastSwapWidth = 0;
|
||||||
int lastSwapHeight = 0;
|
int lastSwapHeight = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -76,6 +76,8 @@ VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &s
|
||||||
// Textures that are already scaled in the texture lump will not get replaced by hires textures.
|
// Textures that are already scaled in the texture lump will not get replaced by hires textures.
|
||||||
int flags = state.mMaterial->isExpanded() ? CTF_Expand : (gl_texture_usehires && !tex->isScaled() && clampmode <= CLAMP_XY) ? CTF_CheckHires : 0;
|
int flags = state.mMaterial->isExpanded() ? CTF_Expand : (gl_texture_usehires && !tex->isScaled() && clampmode <= CLAMP_XY) ? CTF_CheckHires : 0;
|
||||||
|
|
||||||
|
if (tex->isHardwareCanvas()) static_cast<FCanvasTexture*>(tex)->NeedUpdate();
|
||||||
|
|
||||||
DescriptorKey key;
|
DescriptorKey key;
|
||||||
key.clampmode = clampmode;
|
key.clampmode = clampmode;
|
||||||
key.translation = translation;
|
key.translation = translation;
|
||||||
|
@ -92,12 +94,12 @@ VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &s
|
||||||
int numLayers = mat->GetLayers();
|
int numLayers = mat->GetLayers();
|
||||||
|
|
||||||
WriteDescriptors update;
|
WriteDescriptors update;
|
||||||
update.addCombinedImageSampler(descriptorSet.get(), 0, GetImageView(tex, clampmode, translation, flags), sampler, mImageLayout);
|
update.addCombinedImageSampler(descriptorSet.get(), 0, GetImageView(tex, translation, flags), sampler, mImageLayout);
|
||||||
for (int i = 1; i < numLayers; i++)
|
for (int i = 1; i < numLayers; i++)
|
||||||
{
|
{
|
||||||
FTexture *layer;
|
FTexture *layer;
|
||||||
auto systex = static_cast<VkHardwareTexture*>(mat->GetLayer(i, 0, &layer));
|
auto systex = static_cast<VkHardwareTexture*>(mat->GetLayer(i, 0, &layer));
|
||||||
update.addCombinedImageSampler(descriptorSet.get(), i, systex->GetImageView(layer, clampmode, 0, mat->isExpanded() ? CTF_Expand : 0), sampler, systex->mImageLayout);
|
update.addCombinedImageSampler(descriptorSet.get(), i, systex->GetImageView(layer, 0, mat->isExpanded() ? CTF_Expand : 0), sampler, systex->mImageLayout);
|
||||||
}
|
}
|
||||||
update.updateSets(fb->device);
|
update.updateSets(fb->device);
|
||||||
}
|
}
|
||||||
|
@ -105,40 +107,67 @@ VulkanDescriptorSet *VkHardwareTexture::GetDescriptorSet(const FMaterialState &s
|
||||||
return descriptorSet.get();
|
return descriptorSet.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
VulkanImageView *VkHardwareTexture::GetImageView(FTexture *tex, int clampmode, int translation, int flags)
|
VulkanImage *VkHardwareTexture::GetImage(FTexture *tex, int translation, int flags)
|
||||||
{
|
{
|
||||||
if (!mImage)
|
if (!mImage)
|
||||||
{
|
{
|
||||||
if (!tex->isHardwareCanvas())
|
CreateImage(tex, translation, flags);
|
||||||
|
}
|
||||||
|
return mImage.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
VulkanImageView *VkHardwareTexture::GetImageView(FTexture *tex, int translation, int flags)
|
||||||
|
{
|
||||||
|
if (!mImageView)
|
||||||
|
{
|
||||||
|
CreateImage(tex, translation, flags);
|
||||||
|
}
|
||||||
|
return mImageView.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VkHardwareTexture::CreateImage(FTexture *tex, int translation, int flags)
|
||||||
|
{
|
||||||
|
if (!tex->isHardwareCanvas())
|
||||||
|
{
|
||||||
|
if (translation <= 0)
|
||||||
{
|
{
|
||||||
if (translation <= 0)
|
translation = -translation;
|
||||||
{
|
|
||||||
translation = -translation;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto remap = TranslationToTable(translation);
|
|
||||||
translation = remap == nullptr ? 0 : remap->GetUniqueIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool needmipmap = (clampmode <= CLAMP_XY);
|
|
||||||
|
|
||||||
FTextureBuffer texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData);
|
|
||||||
CreateTexture(texbuffer.mWidth, texbuffer.mHeight, 4, VK_FORMAT_B8G8R8A8_UNORM, texbuffer.mBuffer);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
static const uint32_t testpixels[4 * 4] =
|
auto remap = TranslationToTable(translation);
|
||||||
{
|
translation = remap == nullptr ? 0 : remap->GetUniqueIndex();
|
||||||
0xff0000ff, 0xff0000ff, 0xffff00ff, 0xffff00ff,
|
|
||||||
0xff0000ff, 0xff0000ff, 0xffff00ff, 0xffff00ff,
|
|
||||||
0xff00ff00, 0xff00ff00, 0x0000ffff, 0xff00ffff,
|
|
||||||
0xff00ff00, 0xff00ff00, 0x0000ffff, 0xff00ffff,
|
|
||||||
};
|
|
||||||
CreateTexture(4, 4, 4, VK_FORMAT_R8G8B8A8_UNORM, testpixels);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FTextureBuffer texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData);
|
||||||
|
CreateTexture(texbuffer.mWidth, texbuffer.mHeight, 4, VK_FORMAT_B8G8R8A8_UNORM, texbuffer.mBuffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto fb = GetVulkanFrameBuffer();
|
||||||
|
|
||||||
|
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
int w = tex->GetWidth();
|
||||||
|
int h = tex->GetHeight();
|
||||||
|
|
||||||
|
ImageBuilder imgbuilder;
|
||||||
|
imgbuilder.setFormat(format);
|
||||||
|
imgbuilder.setSize(w, h);
|
||||||
|
imgbuilder.setUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
|
||||||
|
mImage = imgbuilder.create(fb->device);
|
||||||
|
mImage->SetDebugName("VkHardwareTexture.mImage");
|
||||||
|
|
||||||
|
ImageViewBuilder viewbuilder;
|
||||||
|
viewbuilder.setImage(mImage.get(), format);
|
||||||
|
mImageView = viewbuilder.create(fb->device);
|
||||||
|
mImageView->SetDebugName("VkHardwareTexture.mImageView");
|
||||||
|
|
||||||
|
auto cmdbuffer = fb->GetUploadCommands();
|
||||||
|
|
||||||
|
PipelineBarrier imageTransition;
|
||||||
|
imageTransition.addImage(mImage.get(), VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 0, VK_ACCESS_SHADER_READ_BIT);
|
||||||
|
imageTransition.execute(cmdbuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
}
|
}
|
||||||
return mImageView.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat format, const void *pixels)
|
void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat format, const void *pixels)
|
||||||
|
|
|
@ -39,8 +39,11 @@ public:
|
||||||
VkHardwareTexture *Prev = nullptr;
|
VkHardwareTexture *Prev = nullptr;
|
||||||
VkHardwareTexture *Next = nullptr;
|
VkHardwareTexture *Next = nullptr;
|
||||||
|
|
||||||
|
VulkanImage *GetImage(FTexture *tex, int translation, int flags);
|
||||||
|
VulkanImageView *GetImageView(FTexture *tex, int translation, int flags);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VulkanImageView *GetImageView(FTexture *tex, int clampmode, int translation, int flags);
|
void CreateImage(FTexture *tex, int translation, int flags);
|
||||||
|
|
||||||
void CreateTexture(int w, int h, int pixelsize, VkFormat format, const void *pixels);
|
void CreateTexture(int w, int h, int pixelsize, VkFormat format, const void *pixels);
|
||||||
void GenerateMipmaps(VulkanImage *image, VulkanCommandBuffer *cmdbuffer);
|
void GenerateMipmaps(VulkanImage *image, VulkanCommandBuffer *cmdbuffer);
|
||||||
|
|
Loading…
Reference in a new issue