This commit is contained in:
Asuka 2020-03-28 07:12:41 +08:00
parent e7320adac7
commit 0ab0e51e5c
5 changed files with 74 additions and 19 deletions

View file

@ -51,6 +51,9 @@ https://gpuopen.com/concurrent-execution-asynchronous-queues/
Synchronization Examples
https://github.com/KhronosGroup/Vulkan-Docs/wiki/Synchronization-Examples
Official HLSL to SPIR-V Feature Mapping Manual
https://github.com/Microsoft/DirectXShaderCompiler/blob/master/docs/SPIR-V.rst

View file

@ -40,7 +40,8 @@ public:
ResourceMemoryType getResourceMemoryType() const
{
// TODO
// From IDA
return static_cast<ResourceMemoryType>(m_vsharp.mtype_L1s << 5 | m_vsharp.mtype << 2 | m_vsharp.mtype_L2);
}
void *getBaseAddress() const

View file

@ -561,34 +561,34 @@ void GnmCommandBufferDraw::bindImmConstBuffer(pssl::PsslProgramType shaderType,
}
void GnmCommandBufferDraw::bindImmBuffer(
pssl::PsslProgramType shaderType,
const PsslShaderResource& res)
pssl::PsslProgramType shaderType,
const GcnShaderResourceInstance& res)
{
const GnmBuffer* vsharp = reinterpret_cast<const GnmBuffer*>(res.resource);
const GnmBuffer* vsharp = reinterpret_cast<const GnmBuffer*>(res.res.resource);
GnmBufferCreateInfo info = {};
info.buffer = vsharp;
info.stages = cvt::convertShaderStage(shaderType);
info.usageType = kShaderInputUsageImmResource;
info.usageType = res.usageType;
auto dataBuffer = m_factory.grabBuffer(info);
VkDeviceSize bufferSize = vsharp->getSize();
m_context->updateBuffer(dataBuffer, 0, bufferSize, vsharp->getBaseAddress());
uint32_t regSlot = computeResBinding(shaderType, res.startRegister);
uint32_t regSlot = computeResBinding(shaderType, res.res.startRegister);
m_context->bindResourceBuffer(regSlot, dataBuffer);
}
void GnmCommandBufferDraw::bindImmTexture(
pssl::PsslProgramType shaderType,
const PsslShaderResource& res)
pssl::PsslProgramType shaderType,
const GcnShaderResourceInstance& res)
{
const GnmTexture* tsharp = reinterpret_cast<const GnmTexture*>(res.resource);
const GnmTexture* tsharp = reinterpret_cast<const GnmTexture*>(res.res.resource);
GnmTextureCreateInfo info = {};
info.texture = tsharp;
info.stages = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
info.usageType = kShaderInputUsageImmResource;
info.stages = cvt::convertShaderStage(shaderType);
info.usageType = res.usageType;
auto image = m_factory.grabImage(info);
auto imgInfo = image.image->info();
@ -631,7 +631,7 @@ void GnmCommandBufferDraw::bindImmTexture(
free(untiledData);
}
uint32_t regSlot = computeResBinding(PsslProgramType::PixelShader, res.startRegister);
uint32_t regSlot = computeResBinding(PsslProgramType::PixelShader, res.res.startRegister);
m_context->bindResourceView(regSlot, image.view, nullptr);
}
@ -641,11 +641,11 @@ void GnmCommandBufferDraw::bindImmResource(
{
if (res.sharpType == PsslSharpType::VSharp)
{
bindImmBuffer(shaderType, res.res);
bindImmBuffer(shaderType, res);
}
else
{
bindImmTexture(shaderType, res.res);
bindImmTexture(shaderType, res);
}
}

View file

@ -173,11 +173,11 @@ private:
const PsslShaderResource& res);
void bindImmBuffer(
pssl::PsslProgramType shaderType,
const PsslShaderResource& res);
pssl::PsslProgramType shaderType,
const GcnShaderResourceInstance& res);
void bindImmTexture(
pssl::PsslProgramType shaderType,
const PsslShaderResource& res);
pssl::PsslProgramType shaderType,
const GcnShaderResourceInstance& res);
void bindImmResource(
pssl::PsslProgramType shaderType,
const GcnShaderResourceInstance& res);

View file

@ -155,6 +155,39 @@ RcPtr<VltBuffer> GnmResourceFactory::createIndex(const GnmIndexBuffer& desc)
RcPtr<VltBuffer> GnmResourceFactory::createBuffer(const GnmBufferCreateInfo& desc)
{
// +--------------------------------+----------------------------------------------+
// | Gnm Buffer | Vulkan Buffer |
// +--------------------------------+----------------------------------------------+
// | VertexBuffer | Vertex Buffer |
// | DataBuffer | Uniform Texel Buffer (uniform samplerbuffer) |
// | RW_DataBuffer | Storage Texel Buffer (uniform imageBuffer) |
// | RegularBuffer/RW_RegularBuffer | Storage Buffer |
// | ConstantBuffer | Uniform Buffer |
// | ByteBuffer/RW_ByteBuffer | Storage Buffer |
// +--------------------------------+----------------------------------------------+
// Here is our buffer mapping table.
// The table references from:
// https://github.com/Microsoft/DirectXShaderCompiler/blob/master/docs/SPIR-V.rst#constanttexturestructuredbyte-buffers
//
// DataBuffer/RW_DataBuffer is mapped to TBO,
// and is supposed to be accessed by format conversion buffer access instructions in shader code,
// like buffer_load_format_xxx and buffer_store_format_xxx.
//
// While other buffers are mapped to VBO, UBO or SSBO accordingly,
// they are supposed to be accessed by non format conversion instructions,
// like buffer_load_xxx or buffer_atomic_xxx or etc.
//
// Note:
// 1. A DataBuffer with DataFormat set to kDataFormatR32Float is the same type
// as a RegularBuffer with stride set to 4.
// In such case, it's legal to initialize a RegularBuffer on Gnm side then
// declare it as a DataBuffer in shader code.
//
// 2. It's legal to initialize a Buffer with RW memory type (e.g. kResourceMemoryTypeGC) on Gnm side
// while declare it as a RO Buffer in shader code, as long as the shader doesn't
// write to the buffer.
VkBufferUsageFlags usage = {};
VkAccessFlags access = {};
@ -173,8 +206,26 @@ RcPtr<VltBuffer> GnmResourceFactory::createBuffer(const GnmBufferCreateInfo& des
access = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
}
break;
case pssl::kShaderInputUsageImmRwResource:
case pssl::kShaderInputUsageImmResource:
case pssl::kShaderInputUsageImmRwResource:
{
ResourceMemoryType memType = desc.buffer->getResourceMemoryType();
LOG_ASSERT(memType == kResourceMemoryTypeGC || memType == kResourceMemoryTypeRO, "unsupported buffer memory type %d", memType);
if (memType == kResourceMemoryTypeRO)
{
// Read only buffer
usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
access = VK_ACCESS_SHADER_READ_BIT;
}
else
{
// Read write buffer
usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
access = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
}
}
break;
default:
LOG_ASSERT(false, "unsupported buffer usage type %d", inputUsageType);
break;