DirectX/DirectX 3D_(구)

22_RawBuffer (CS)

컴맹학자 2021. 7. 28. 11:03
728x90

Buffers.cpp, h


22_ByteAddress.fx

더보기
//c++ 에선 RawBuffer라고 부르고 쉐이더에선 ByteAddress 부름
RWByteAddressBuffer Output; //출력용이면 앞에 RW붙여줘야함
ByteAddressBuffer Input;

//저장용 (Output)
struct Group
{
    uint3 GroupID;
    uint3 GroupThreadID;
    uint3 DispatchThreadID;
    uint GroupIndex;
};

//받아오는용(Output)
struct ComputeInput
{
    uint3 GroupID : SV_GroupID;
    uint3 GroupThreadID : SV_GroupThreadID;
    uint3 DispatchThreadID : SV_DispatchThreadID;
    uint  GroupIndex : SV_GroupIndex;
};

[numthreads(10, 8, 3)] //ComputeShader용 Atuebute선언
void CS(ComputeInput input)
{
    Group gorup;
    
    //시스템값을 받아올때 asuint() 함수로 
    gorup.GroupID = asuint(input.GroupID);
    gorup.GroupThreadID = asuint(input.GroupThreadID);
    gorup.DispatchThreadID = asuint(input.DispatchThreadID);
    gorup.GroupIndex = asuint(input.GroupIndex);

    //-----------------------입력용-----------------------------------
    uint inAddress = (input.GroupID.x * 240 + input.GroupIndex) * 4;
    float value = floor(asfloat(Input.Load(inAddress))) + 0.99f; //test 용
    
    
    //------------------------출력용-----------------------------------
    //주소용 (처음 위치) 10 * 4 -> ComputeInput구조체 크기 * 4바이트
    //uint outAddress = (input.GroupID.x * 240 + input.GroupIndex) * 10 * 4;
    uint outAddress = (input.GroupID.x * 240 + input.GroupIndex) * 11 * 4;
    
    //Store[갯수] 바이트 형태로 저장
    Output.Store3(outAddress + 0,  asuint(gorup.GroupID));
    Output.Store3(outAddress + 12, asuint(gorup.GroupThreadID));
    Output.Store3(outAddress + 24, asuint(gorup.DispatchThreadID));
    Output.Store (outAddress + 36, asuint(gorup.GroupIndex));
    
    Output.Store(outAddress + 40, asuint(value));
    
}

technique11 T0
{
    pass P0
    {
        //계산용은 사용할 필요 없지만 필수로 선언 해줘야함
        SetVertexShader(NULL);
        SetPixelShader(NULL);

        SetComputeShader(CompileShader(cs_5_0, CS()));
    }

}

RawBufferDemo.cpp, h

더보기
#include "stdafx.h"
#include "RawBufferDemo.h"

void RawBufferDemo::Initialize()
{
	Shader* shader = new Shader(L"22_ByteAddress.fxo");

	UINT count = 2 * 10 * 8 * 3 ;	//그룹

	struct Output
	{
		UINT GroupID[3];
		UINT GroupThreadID[3];
		UINT DispatchThreadID[3];
		UINT GroupIndex;
		float RetValue; //리턴 받을값
	};

	float* data = new float[count];
	for (UINT i = 0; i < count; i++)
		data[i] = Math::Random(0.0f, 1000.0f); //임의로 넣을 데이터

	RawBuffer* rawBuffer = new RawBuffer(data, sizeof(float) * count, sizeof(Output) * count);

	//Draw 렌더링용 Dispatch 값을 받아오는용 (technique11, pass , 그룹x, 그룹y, 그룹z)
	shader->AsSRV("Input")->SetResource(rawBuffer->SRV());
	shader->AsUAV("Output")->SetUnorderedAccessView(rawBuffer->UAV());
	shader->Dispatch(0, 0, 2, 1, 1); //그룹 갯수도 바뀌면 count값도 변경필요

	Output* output = new Output[count];
	rawBuffer->CopyFromInput(output);




	FILE* file;
	fopen_s(&file, "../RawBuffer.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);
}

 

#pragma once
#include "Systems/IExecute.h"

class RawBufferDemo : public IExecute
{
public:
	virtual void Initialize() 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:


};

보충

더보기

RawBuffer 설명

ttps://docs.microsoft.com/ko-kr/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics

 

단순 계산할때 사용하고 주로 사용 하지는 않음 하지만 21_Thread에서 이제는 값을 받고 쓰는 개념을 배움