Skip to content

[spirv] Suboptimal code generation for groupshared struct member functions/functions accepting groupshared arrays #1977

@pmichniewski

Description

@pmichniewski

Currently DXC in SPIRV mode generates suboptimal code for member functions of groupshared structs and for functions that take groupshared arrays as params.

Testcase:

#define TILE_GROUP_SIZE_X 8
#define TILE_GROUP_SIZE_Y 8

struct testStruct
{
	float Data[1 + TILE_GROUP_SIZE_X + 1][1 + TILE_GROUP_SIZE_X + 1];

	float3x3 testFunc(uint topLeftX, uint topLeftY)
	{
		float3x3 toRet;

		toRet[0][0] = Data[topLeftX][topLeftY];
		toRet[0][1] = Data[topLeftX][topLeftY+1];
		toRet[0][2] = Data[topLeftX][topLeftY+2];

		toRet[1][0] = Data[topLeftX+1][topLeftY];
		toRet[1][1] = Data[topLeftX+1][topLeftY+1];
		toRet[1][2] = Data[topLeftX+1][topLeftY+2];

		toRet[2][0] = Data[topLeftX+2][topLeftY];
		toRet[2][1] = Data[topLeftX+2][topLeftY+1];
		toRet[2][2] = Data[topLeftX+2][topLeftY+2];

		return toRet;
	}
};

groupshared testStruct sharedStruct;

RWStructuredBuffer<float> testOut;

[numthreads(TILE_GROUP_SIZE_X, TILE_GROUP_SIZE_Y, 1)]
void testMain( uint3 DispatchThreadId	: SV_DispatchThreadID,
			   uint3 GroupThreadID : SV_GroupThreadID,
			   uint3 GroupID : SV_GroupID )
{
    sharedStruct.Data[GroupThreadID.x][GroupThreadID.y] = (float)GroupID.x;

    GroupMemoryBarrierWithGroupSync();

    float3x3 result = sharedStruct.testFunc( GroupThreadID.x, GroupThreadID.y );
    testOut[GroupThreadID.x] = result[0][0];
}

This causes a temporary variable to be created each for time testFunc is called, which in turn causes a lot of copies to be executed at runtime (50x ds_read2_b32 + 100x buffer_store_dword + 50x ds_write2_b32 are emitted by the GCN compiler).

Metadata

Metadata

Assignees

Labels

spirvWork related to SPIR-V

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions