mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-02-26 00:45:49 +00:00
Vulkan hw tess: Use pushbuffers instead of temp images to upload data.
This commit is contained in:
parent
5d6a830288
commit
9cd4db5f18
@ -155,6 +155,7 @@ protected:
|
||||
int numPatches;
|
||||
class TessellationDataTransfer {
|
||||
protected:
|
||||
// TODO: These aren't used by all backends.
|
||||
int prevSize;
|
||||
int prevSizeTex;
|
||||
int prevSizeCol;
|
||||
|
@ -294,6 +294,9 @@ void DrawEngineVulkan::BeginFrame() {
|
||||
frame->pushVertex->Begin(vulkan_);
|
||||
frame->pushIndex->Begin(vulkan_);
|
||||
|
||||
// TODO: How can we make this nicer...
|
||||
((TessellationDataTransferVulkan *)tessDataTransfer)->SetPushBuffer(frame->pushUBO);
|
||||
|
||||
// TODO : Find a better place to do this.
|
||||
if (!nullTexture_) {
|
||||
ILOG("INIT : Creating null texture");
|
||||
@ -1096,53 +1099,82 @@ DrawEngineVulkan::TessellationDataTransferVulkan::~TessellationDataTransferVulka
|
||||
}
|
||||
|
||||
void DrawEngineVulkan::TessellationDataTransferVulkan::PrepareBuffers(float *&pos, float *&tex, float *&col, int size, bool hasColor, bool hasTexCoords) {
|
||||
int rowPitch;
|
||||
ILOG("INIT : Prep tess");
|
||||
|
||||
VkCommandBuffer cmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER);
|
||||
// Position
|
||||
if (prevSize < size) {
|
||||
prevSize = size;
|
||||
delete data_tex[0];
|
||||
data_tex[0] = new VulkanTexture(vulkan_, nullptr); // TODO: Should really use an allocator.
|
||||
data_tex[0]->CreateDirect(cmd, size, 1, 1, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
delete data_tex[0];
|
||||
data_tex[0] = new VulkanTexture(vulkan_, nullptr); // TODO: Should really use an allocator.
|
||||
data_tex[0]->CreateDirect(cmd, size, 1, 1, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
}
|
||||
pos = (float *)data_tex[0]->Lock(0, &rowPitch);
|
||||
posSize_ = size;
|
||||
pos = (float *)push_->Push(size * sizeof(float) * 4, &posOffset_, &posBuf_);
|
||||
|
||||
// Texcoords
|
||||
delete data_tex[1];
|
||||
data_tex[1] = nullptr;
|
||||
if (hasTexCoords) {
|
||||
if (prevSizeTex < size) {
|
||||
prevSizeTex = size;
|
||||
data_tex[1] = new VulkanTexture(vulkan_, nullptr); // TODO: Should really use an allocator.
|
||||
data_tex[1]->CreateDirect(cmd, size, 1, 1, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
delete data_tex[1];
|
||||
data_tex[1] = new VulkanTexture(vulkan_, nullptr); // TODO: Should really use an allocator.
|
||||
data_tex[1]->CreateDirect(cmd, size, 1, 1, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
}
|
||||
tex = (float *)data_tex[1]->Lock(0, &rowPitch);
|
||||
tex = (float *)push_->Push(size * sizeof(float) * 4, &texOffset_, &texBuf_);
|
||||
texSize_ = size;
|
||||
} else {
|
||||
texSize_ = 0;
|
||||
tex = nullptr;
|
||||
}
|
||||
|
||||
// Color
|
||||
int sizeColor = hasColor ? size : 1;
|
||||
if (prevSizeCol < sizeColor) {
|
||||
prevSizeCol = sizeColor;
|
||||
colSize_ = hasColor ? size : 1;
|
||||
delete data_tex[2];
|
||||
data_tex[2] = new VulkanTexture(vulkan_, nullptr); // TODO: Should really use an allocator.
|
||||
data_tex[2]->CreateDirect(cmd, colSize_, 1, 1, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
|
||||
delete data_tex[2];
|
||||
data_tex[2] = new VulkanTexture(vulkan_, nullptr); // TODO: Should really use an allocator.
|
||||
data_tex[2]->CreateDirect(cmd, sizeColor, 1, 1, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
}
|
||||
col = (float *)data_tex[2]->Lock(0, &rowPitch);
|
||||
col = (float *)push_->Push(size * sizeof(float) * 4, &colOffset_, &colBuf_);
|
||||
}
|
||||
|
||||
void DrawEngineVulkan::TessellationDataTransferVulkan::SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) {
|
||||
VkCommandBuffer cmd = (VkCommandBuffer)draw_->GetNativeObject(Draw::NativeObject::INIT_COMMANDBUFFER);
|
||||
// Position
|
||||
data_tex[0]->Unlock(cmd);
|
||||
data_tex[0]->UploadMip(cmd, 0, posSize_, 1, posBuf_, posOffset_, posSize_);
|
||||
data_tex[0]->EndCreate(cmd);
|
||||
|
||||
// Texcoords
|
||||
if (hasTexCoords)
|
||||
data_tex[1]->Unlock(cmd);
|
||||
if (hasTexCoords) {
|
||||
data_tex[1]->UploadMip(cmd, 0, texSize_, 1, texBuf_, texOffset_, texSize_);
|
||||
data_tex[1]->EndCreate(cmd);
|
||||
}
|
||||
|
||||
// Color
|
||||
data_tex[2]->Unlock(cmd);
|
||||
data_tex[2]->UploadMip(cmd, 0, colSize_, 1, colBuf_, colOffset_, colSize_);
|
||||
data_tex[2]->EndCreate(cmd);
|
||||
}
|
||||
|
||||
void DrawEngineVulkan::TessellationDataTransferVulkan::CreateSampler() {
|
||||
VkSamplerCreateInfo samp = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
|
||||
samp.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samp.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samp.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samp.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||
samp.compareOp = VK_COMPARE_OP_NEVER;
|
||||
samp.flags = 0;
|
||||
samp.magFilter = VK_FILTER_NEAREST;
|
||||
samp.minFilter = VK_FILTER_NEAREST;
|
||||
samp.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_ANISOTROPY) && g_Config.iAnisotropyLevel > 0) {
|
||||
// Docs say the min of this value and the supported max are used.
|
||||
samp.maxAnisotropy = 1 << g_Config.iAnisotropyLevel;
|
||||
samp.anisotropyEnable = true;
|
||||
} else {
|
||||
samp.maxAnisotropy = 1.0f;
|
||||
samp.anisotropyEnable = false;
|
||||
}
|
||||
|
||||
samp.maxLod = 1.0f;
|
||||
samp.minLod = 0.0f;
|
||||
samp.mipLodBias = 0.0f;
|
||||
|
||||
VkResult res = vkCreateSampler(vulkan_->GetDevice(), &samp, nullptr, &sampler);
|
||||
assert(res == VK_SUCCESS);
|
||||
}
|
@ -261,47 +261,34 @@ private:
|
||||
|
||||
// Hardware tessellation
|
||||
class TessellationDataTransferVulkan : public TessellationDataTransfer {
|
||||
private:
|
||||
VulkanContext *vulkan_;
|
||||
Draw::DrawContext *draw_;
|
||||
VulkanTexture *data_tex[3]{};
|
||||
VkSampler sampler = VK_NULL_HANDLE;
|
||||
public:
|
||||
TessellationDataTransferVulkan(VulkanContext *vulkan, Draw::DrawContext *draw);
|
||||
~TessellationDataTransferVulkan();
|
||||
|
||||
void SetPushBuffer(VulkanPushBuffer *push) { push_ = push; }
|
||||
void SendDataToShader(const float *pos, const float *tex, const float *col, int size, bool hasColor, bool hasTexCoords) override;
|
||||
void PrepareBuffers(float *&pos, float *&tex, float *&col, int size, bool hasColor, bool hasTexCoords) override;
|
||||
|
||||
VulkanTexture *GetTexture(int i) const { return data_tex[i]; }
|
||||
|
||||
VkSampler GetSampler() const { return sampler; }
|
||||
void CreateSampler() {
|
||||
VkSamplerCreateInfo samp = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
|
||||
samp.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samp.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samp.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samp.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||
samp.compareOp = VK_COMPARE_OP_NEVER;
|
||||
samp.flags = 0;
|
||||
samp.magFilter =VK_FILTER_NEAREST;
|
||||
samp.minFilter = VK_FILTER_NEAREST;
|
||||
samp.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||
void CreateSampler();
|
||||
private:
|
||||
VulkanContext *vulkan_;
|
||||
Draw::DrawContext *draw_;
|
||||
VulkanTexture *data_tex[3]{};
|
||||
VkSampler sampler = VK_NULL_HANDLE;
|
||||
VulkanPushBuffer *push_; // Updated each frame.
|
||||
|
||||
if (gstate_c.Supports(GPU_SUPPORTS_ANISOTROPY) && g_Config.iAnisotropyLevel > 0) {
|
||||
// Docs say the min of this value and the supported max are used.
|
||||
samp.maxAnisotropy = 1 << g_Config.iAnisotropyLevel;
|
||||
samp.anisotropyEnable = true;
|
||||
} else {
|
||||
samp.maxAnisotropy = 1.0f;
|
||||
samp.anisotropyEnable = false;
|
||||
}
|
||||
int posSize_ = 0;
|
||||
uint32_t posOffset_ = 0;
|
||||
VkBuffer posBuf_ = 0;
|
||||
int texSize_ = 0;
|
||||
uint32_t texOffset_ = 0;
|
||||
VkBuffer texBuf_ = 0;
|
||||
int colSize_ = 0;
|
||||
uint32_t colOffset_ = 0;
|
||||
VkBuffer colBuf_ = 0;
|
||||
|
||||
samp.maxLod = 1.0f;
|
||||
samp.minLod = 0.0f;
|
||||
samp.mipLodBias = 0.0f;
|
||||
|
||||
VkResult res = vkCreateSampler(vulkan_->GetDevice(), &samp, nullptr, &sampler);
|
||||
assert(res == VK_SUCCESS);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user