[DirectX11] 061 Thread Group, SV_GroupID
DirectX 11에서 Thread Group은 GPU 상에서 함께 실행되는 셰이더 호출의 집합을 의미한다. Thread Group은 GPU 상에서 비그래픽 처리를 허용하는 그래픽 파이프라인의 프로그래밍 가능한 단계인 컴퓨팅 셰이더에 사용된다.
목차
Thread Group
DirectX 11에서 Thread Group은 GPU 상에서 함께 실행되는 셰이더 호출의 집합을 의미한다. Thread Group은 GPU 상에서 비그래픽 처리를 허용하는 그래픽 파이프라인의 프로그래밍 가능한 단계인 컴퓨팅 셰이더에 사용된다.
Thread Group은 세 가지 값, 즉 각 차원을 따르는 그룹의 스레드 수(thread group dimensions), 그룹의 스레드 수(thread group size) 및 총 스레드 그룹 수(dispatch count)로 정의된다. 이러한 값은 계산 셰이더의 Dispatch() 메서드를 사용하여 설정된다.
SV_GroupID
SV_GroupID 시스템 값은 현재 스레드 그룹의 ID를 제공하는 HLSL(DirectX에서 사용되는 셰이더 언어)의 기본 제공 변수이다. 이 변수는 스레드 동기화 및 메모리 액세스와 같은 동일한 그룹 내 스레드 간의 조정이 필요한 그룹 수준 작업을 수행하는 데 사용할 수 있다.
SV_GroupID는 각 차원에서 현재 스레드 그룹의 인덱스를 나타내는 3개의 값을 가지는 벡터이다. 예를 들어 스레드 그룹 차원이 (8, 8, 1)로 설정된 경우 SV_GroupID 변수는 x 및 y 차원에서 현재 스레드 그룹의 인덱스를 나타내는 (0, 0, 0) ~ (7, 7, 0) 범위의 값을 가진다.
전체적으로 스레드 그룹 및 SV_GroupID는 GPU에서 효율적인 병렬 처리를 가능하게 하는 컴퓨팅 셰이더의 중요한 개념이다.
Microsoft 공식문서
https://learn.microsoft.com/ko-kr/windows/win32/direct3dhlsl/sv-groupid
Shader | |
RawBuffer.fx | |
Framework | |
Render | |
Buffer.h .cpp | |
UnitTest | |
DirectCompute | |
RawBufferDemo.h .cpp | |
Main.h .cpp |
RawBuffer.fx
RawBuffer.fx
ByteAddressBuffer Input; //SRV
RWByteAddressBuffer Output; //UAV
struct Group
{
uint3 GroupID;
uint3 GroupThreadID;
uint3 DispatchThreadID;
uint GroupIndex;
float RetValue;
};
struct ComputeInput
{
uint3 GroupID : SV_GroupID;
uint3 GroupThreadID : SV_GroupThreadID;
uint3 DispatchThreadID : SV_DispatchThreadID;
uint GroupIndex : SV_GroupIndex;
};
//thread 하나하나가 함수를 물고 진행한다.
[numthreads(10, 8, 3)] //x, y, z
void CS(ComputeInput input)
{
Group group;
group.GroupID = asuint(input.GroupID); //asuint는 uint로 캐스팅해주는 함수
group.GroupThreadID = asuint(input.GroupThreadID);
group.DispatchThreadID = asuint(input.DispatchThreadID);
group.GroupIndex = asuint(input.GroupIndex);
uint index = input.GroupID.x * 10 * 8 * 3 + input.GroupIndex;
uint outAddress = index * 11 * 4; //thread 개수 늘려줌.
uint inAddress = index * 4;
group.RetValue = asfloat(Input.Load(inAddress));
Output.Store3(outAddress + 0, asuint(group.GroupID)); //12
Output.Store3(outAddress + 12, asuint(group.GroupThreadID)); //24
Output.Store3(outAddress + 24, asuint(group.DispatchThreadID)); //36
Output.Store(outAddress + 36, asuint(group.GroupIndex)); //40
Output.Store(outAddress + 40, asuint(group.RetValue));
}
technique11 T0
{
pass P0
{
SetVertexShader(NULL);
SetPixelShader(NULL);
//cs_5_0는 DX11에서 사용하는 Shader 버젼
SetComputeShader(CompileShader(cs_5_0, CS()));
}
}
RawBufferDemo
RawBufferDemo.h
#pragma once
#include "Systems/IExecute.h"
class RawBufferDemo : public IExecute
{
public:
virtual void Initialize() override;
virtual void Ready() override {}
virtual void Destroy() override {}
virtual void Update() override;
virtual void PreRender() override {}
virtual void Render() override;
virtual void PostRender() override {}
virtual void ResizeScreen() override {}
private:
};
RawBufferDemo.cpp
#include "stdafx.h"
#include "RawBufferDemo.h"
void RawBufferDemo::Initialize()
{
Shader* shader = new Shader(L"60_RawBuffer.fx");
UINT count = 2 * 10 * 8 * 3; //x2 //shader->Dispatch에서 x를 2로 늘려주었다.
struct Output
{
UINT GroupID[3];
UINT GroupThreadID[3];
UINT DispatchThreadID[3];
UINT GroupIndex;
float RetValue;
};
//RawBuffer* rawBuffer = new RawBuffer(NULL, 0, sizeof(Output) * count);
struct Input
{
float Value = 0.0f;
};
Input* input = new Input[count];
for (int i = 0; i < count; i++)
input[i].Value = Math::Random(0.0f, 10000.0f);
RawBuffer* rawBuffer = new RawBuffer(input, sizeof(Input) * count, sizeof(Output) * count);
shader->AsSRV("Input")->SetResource(rawBuffer->SRV());
shader->AsUAV("Output")->SetUnorderedAccessView(rawBuffer->UAV());
shader->Dispatch(0, 0, 2, 1, 1);
Output* output = new Output[count];
rawBuffer->CopyFromOuput(output);
FILE* file;
fopen_s(&file, "../Raw.csv", "w");
for (UINT i = 0; i < count; i++)
{
Output temp = output[i];
fprintf
(
file,
"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%f\n",
i,
temp.GroupID[0], temp.GroupID[1], temp.GroupID[2],
temp.GroupThreadID[0], temp.GroupThreadID[1], temp.GroupThreadID[2],
temp.DispatchThreadID[0], temp.DispatchThreadID[1], temp.DispatchThreadID[2],
temp.GroupIndex, temp.RetValue
);
}
fclose(file);
}
void RawBufferDemo::Update() { }
void RawBufferDemo::Render() { }
UINT count = 2 * 10 * 8 * 3;
- shader->Dispatch에서 x를 2로 늘려주었기 때문에 x2를 하였다.
Input* input = new Input[count];
for (int i = 0; i < count; i++)
input[i].Value = Math::Random(0.0f, 10000.0f);
- input을 배열로 만들어 적용.
실행화면
'⭐ DirectX > DirectX11 3D' 카테고리의 다른 글
[DirectX11] 063 Compute Shader - GetAnimationBone 구현하기 (0) | 2023.03.06 |
---|---|
[DirectX11] 062 Texture Buffer (0) | 2023.03.03 |
[DirectX11] 060 Compute Shader (0) | 2023.02.28 |
[DirectX11] 059 Raw Buffer (0) | 2023.02.28 |
[DirectX11] 058 Direct Compute (0) | 2023.02.27 |
댓글
이 글 공유하기
다른 글
-
[DirectX11] 063 Compute Shader - GetAnimationBone 구현하기
[DirectX11] 063 Compute Shader - GetAnimationBone 구현하기
2023.03.06 -
[DirectX11] 062 Texture Buffer
[DirectX11] 062 Texture Buffer
2023.03.03 -
[DirectX11] 060 Compute Shader
[DirectX11] 060 Compute Shader
2023.02.28 -
[DirectX11] 059 Raw Buffer
[DirectX11] 059 Raw Buffer
2023.02.28