Skip to content

Commit cb60daf

Browse files
committed
Fix scissor rect handling, improve blend state creation, update test cases and fix draw indexed call
1 parent b08964b commit cb60daf

5 files changed

Lines changed: 76 additions & 23 deletions

File tree

src/vrhi_backend.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -420,12 +420,7 @@ bool vhCmdBackendState::BE_PresubmitCommon_PipelineDesc(
420420
graphicsPipelineDesc->renderState.blendState = vhTranslateBlendState( state.stateFlags );
421421
graphicsPipelineDesc->renderState.depthStencilState = vhTranslateDepthStencilState( state.stateFlags, state.frontStencil, state.backStencil );
422422
graphicsPipelineDesc->renderState.rasterState = vhTranslateRasterState( state.stateFlags );
423-
if ( state.viewScissor.z >= 0.0f && state.viewScissor.w >= 0.0f )
424-
{
425-
graphicsPipelineDesc->renderState.rasterState.scissorEnable = true;
426-
}
427-
428-
// Apply depth bias values
423+
graphicsPipelineDesc->renderState.rasterState.scissorEnable = ( state.viewScissor.z >= 0.0f && state.viewScissor.w >= 0.0f );
429424
graphicsPipelineDesc->renderState.rasterState.depthBias = state.depthBias;
430425
graphicsPipelineDesc->renderState.rasterState.depthBiasClamp = state.depthBiasClamp;
431426
graphicsPipelineDesc->renderState.rasterState.slopeScaledDepthBias = state.slopeScaledDepthBias;
@@ -1099,10 +1094,20 @@ bool vhCmdBackendState::BE_PreSubmitCommon_State(
10991094
) );
11001095

11011096
graphicsState->viewport.scissorRects.resize( 0 );
1102-
graphicsState->viewport.scissorRects.push_back( nvrhi::Rect(
1103-
( int ) state.viewScissor.x, ( int ) ( state.viewScissor.x + state.viewScissor.z ),
1104-
( int ) state.viewScissor.y, ( int ) ( state.viewScissor.y + state.viewScissor.w )
1105-
) );
1097+
if ( state.viewScissor.z >= 0.0f && state.viewScissor.w >= 0.0f )
1098+
{
1099+
graphicsState->viewport.scissorRects.push_back( nvrhi::Rect(
1100+
( int ) state.viewScissor.x, ( int ) ( state.viewScissor.x + state.viewScissor.z ),
1101+
( int ) state.viewScissor.y, ( int ) ( state.viewScissor.y + state.viewScissor.w )
1102+
) );
1103+
}
1104+
else
1105+
{
1106+
graphicsState->viewport.scissorRects.push_back( nvrhi::Rect(
1107+
( int ) state.viewRect.x, ( int ) ( state.viewRect.x + state.viewRect.z ),
1108+
( int ) state.viewRect.y, ( int ) ( state.viewRect.y + state.viewRect.w )
1109+
) );
1110+
}
11061111

11071112
// nvrhi::DepthStencilState::dynamicStencilRefValue is false, but we set this any way because it's fun.
11081113
graphicsState->dynamicStencilRefValue = ( uint8_t ) ( ( state.frontStencil & VRHI_STENCIL_FUNC_REF_MASK ) >> VRHI_STENCIL_FUNC_REF_SHIFT );

src/vrhi_device.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ void vhDrawIndexed( vhStateId state, uint32_t indexCount, uint32_t instanceCount
522522
vhDrawCommonInternal(
523523
state,
524524
VRHI_DRAW_INDEXED,
525-
0, // vertexCount (unused for indexed)
525+
indexCount, // vertexCount acts as indexCount for indexed draws
526526
instanceCount,
527527
( uint32_t ) baseVertexLocation, // startVertexLocation acts as baseVertexLocation for indexed
528528
startIndexLocation,

src/vrhi_state.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,12 @@ nvrhi::BlendState vhTranslateBlendState( uint64_t stateFlags )
307307
};
308308

309309
// Write Masks
310-
blendState.targets[0].colorWriteMask = ( nvrhi::ColorMask ) ( stateFlags & 0xF );
310+
nvrhi::ColorMask mask = ( nvrhi::ColorMask ) 0;
311+
if ( stateFlags & VRHI_STATE_WRITE_R ) mask = mask | nvrhi::ColorMask::Red;
312+
if ( stateFlags & VRHI_STATE_WRITE_G ) mask = mask | nvrhi::ColorMask::Green;
313+
if ( stateFlags & VRHI_STATE_WRITE_B ) mask = mask | nvrhi::ColorMask::Blue;
314+
if ( stateFlags & VRHI_STATE_WRITE_A ) mask = mask | nvrhi::ColorMask::Alpha;
315+
blendState.targets[0].colorWriteMask = mask;
311316

312317
// Blend Factors
313318
uint32_t blendBits = ( uint32_t ) ( ( stateFlags & VRHI_STATE_BLEND_MASK ) >> VRHI_STATE_BLEND_SHIFT );
@@ -328,6 +333,12 @@ nvrhi::BlendState vhTranslateBlendState( uint64_t stateFlags )
328333
blendState.targets[0].blendOpAlpha = fnConvertBlendOp( ( blendEq >> 3 ) & 0x7 );
329334
}
330335

336+
// Propagate duplicate settings to all other targets
337+
for ( int i = 1; i < nvrhi::c_MaxRenderTargets; ++i )
338+
{
339+
blendState.targets[i] = blendState.targets[0];
340+
}
341+
331342
blendState.alphaToCoverageEnable = ( stateFlags & VRHI_STATE_BLEND_ALPHA_TO_COVERAGE ) != 0;
332343

333344
return blendState;

test/test_gfx.cpp

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,12 @@ static vhBuffer CreateTestVB( const char* layout, const void* data, uint32_t siz
201201
return buf;
202202
}
203203

204-
static vhBuffer CreateTestIB( const void* data, uint32_t size )
204+
static vhBuffer CreateTestIB( const void* data, uint32_t size, uint16_t flags = VRHI_BUFFER_NONE )
205205
{
206206
vhBuffer buf = vhAllocBuffer();
207207
vhMem* mem = vhAllocMem( size );
208208
memcpy( mem->data(), data, size );
209-
vhCreateIndexBuffer( buf, "TestIB", mem );
209+
vhCreateIndexBuffer( buf, "TestIB", mem, 0, flags );
210210
return buf;
211211
}
212212

@@ -309,6 +309,7 @@ UTEST_F( Graphics, DrawTriangle )
309309
state.SetColourAttachment( 0, rt )
310310
.SetViewRect( glm::vec4( 0, 0, 64, 64 ) )
311311
.SetViewClear( VRHI_CLEAR_COLOR, glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f ) )
312+
.SetStateFlags( VRHI_STATE_WRITE_MASK )
312313
.SetVertexBuffer( vb, 0 )
313314
.SetProgram( vhCreateGfxProgram( vs, ps ) );
314315

@@ -340,14 +341,15 @@ UTEST_F( Graphics, DrawIndexedTriangle )
340341
uint32_t indices[3] = { 0, 1, 2 };
341342

342343
vhBuffer vb = CreateTestVB( "float3 float4", verts, sizeof( verts ) );
343-
vhBuffer ib = CreateTestIB( indices, sizeof( indices ) );
344+
vhBuffer ib = CreateTestIB( indices, sizeof( indices ), VRHI_BUFFER_INDEX32 );
344345
vhShader vs = CreateTestShader( g_simpleVS, VRHI_SHADER_STAGE_VERTEX );
345346
vhShader ps = CreateTestShader( g_solidPS, VRHI_SHADER_STAGE_PIXEL );
346347

347348
vhState state;
348349
state.SetColourAttachment( 0, rt )
349350
.SetViewRect( glm::vec4( 0, 0, 64, 64 ) )
350351
.SetViewClear( VRHI_CLEAR_COLOR, glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f ) )
352+
.SetStateFlags( VRHI_STATE_WRITE_MASK )
351353
.SetVertexBuffer( vb, 0 )
352354
.SetIndexBuffer( ib )
353355
.SetProgram( vhCreateGfxProgram( vs, ps ) );
@@ -388,7 +390,7 @@ UTEST_F( Graphics, DrawTriangleStrip )
388390
.SetViewRect( glm::vec4( 0, 0, 64, 64 ) )
389391
.SetViewClear( VRHI_CLEAR_COLOR, glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f ) )
390392
.SetVertexBuffer( vb, 0 )
391-
.SetStateFlags( VRHI_STATE_PT_TRISTRIP )
393+
.SetStateFlags( VRHI_STATE_WRITE_MASK | VRHI_STATE_PT_TRISTRIP )
392394
.SetProgram( vhCreateGfxProgram( vs, ps ) );
393395

394396
vhStateId sid = 350;
@@ -660,7 +662,7 @@ UTEST_F( Graphics, ScissorTest )
660662
.SetViewRect( glm::vec4( 0, 0, 64, 64 ) )
661663
.SetViewScissor( glm::vec4( 16, 16, 32, 32 ) ) // Center 32x32
662664
.SetViewClear( VRHI_CLEAR_COLOR, glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f ) )
663-
.SetStateFlags( VRHI_STATE_WRITE_RGB )
665+
.SetStateFlags( VRHI_STATE_WRITE_MASK )
664666
.SetVertexBuffer( vb, 0 )
665667
.SetProgram( vhCreateGfxProgram( vs, ps ) );
666668

@@ -685,8 +687,8 @@ UTEST_F( Graphics, MultipleTextures )
685687
vhTexture rt = CreateTestTexture( 64, 64, nvrhi::Format::RGBA8_UNORM );
686688

687689
// Create two source textures
688-
vhTexture t0 = CreateTestTexture( 64, 64, nvrhi::Format::RGBA8_UNORM );
689-
vhTexture t1 = CreateTestTexture( 64, 64, nvrhi::Format::RGBA8_UNORM );
690+
vhTexture t0 = CreateTestTexture( 64, 64, nvrhi::Format::RGBA8_UNORM, VRHI_TEXTURE_NONE );
691+
vhTexture t1 = CreateTestTexture( 64, 64, nvrhi::Format::RGBA8_UNORM, VRHI_TEXTURE_NONE );
690692

691693
// Fill t0 with Red, t1 with Green
692694
vhMem* redData = vhAllocMem( 64 * 64 * 4 ); std::fill( redData->begin(), redData->end(), 0 );
@@ -718,6 +720,7 @@ UTEST_F( Graphics, MultipleTextures )
718720
state.SetColourAttachment( 0, rt )
719721
.SetViewRect( glm::vec4( 0, 0, 64, 64 ) )
720722
.SetViewClear( VRHI_CLEAR_COLOR, glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f ) )
723+
.SetStateFlags( VRHI_STATE_WRITE_MASK )
721724
.SetVertexBuffer( vb, 0 )
722725
.SetTexture( 0, { "t0", -1, t0 } )
723726
.SetTexture( 1, { "t1", -1, t1 } )
@@ -766,6 +769,7 @@ UTEST_F( Graphics, TextureFormats )
766769
state.SetColourAttachment( 0, rt )
767770
.SetViewRect( glm::vec4( 0, 0, 64, 64 ) )
768771
.SetViewClear( VRHI_CLEAR_COLOR, glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f ) )
772+
.SetStateFlags( VRHI_STATE_WRITE_MASK )
769773
.SetVertexBuffer( vb, 0 )
770774
.SetProgram( vhCreateGfxProgram( vs, ps ) );
771775

@@ -776,6 +780,30 @@ UTEST_F( Graphics, TextureFormats )
776780

777781
// 2.0 -> 255, 0.5 -> 127, 0.1 -> 25
778782
EXPECT_TRUE( VerifyPixel( rt, 32, 32, 0xFF197FFF ) );
783+
784+
// Manual verification for RGBA16_FLOAT
785+
vhMem readData;
786+
vhReadTextureSlow( rt, 0, 0, &readData );
787+
vhFinish();
788+
789+
uint64_t offset = ( 32 * 64 + 32 ) * 8; // 8 bytes per pixel
790+
if ( readData.size() > offset + 8 )
791+
{
792+
uint16_t* ptr = ( uint16_t* )&readData[offset];
793+
// expected: 2.0 (0x4000), 0.5 (0x3800), 0.1 (~0x2E66), 1.0 (0x3C00)
794+
// Allow small tolerance for 0.1
795+
bool r = ptr[0] == 0x4000;
796+
bool g = ptr[1] == 0x3800;
797+
bool b = abs( (int)ptr[2] - 0x2E66 ) <= 1;
798+
bool a = ptr[3] == 0x3C00;
799+
EXPECT_TRUE( r && g && b && a );
800+
if ( !( r && g && b && a ) )
801+
UTEST_PRINTF( "TextureFormats Failed: %04X %04X %04X %04X\n", ptr[0], ptr[1], ptr[2], ptr[3] );
802+
}
803+
else
804+
{
805+
EXPECT_TRUE( false ); // Readback failed
806+
}
779807

780808
vhDestroyTexture( rt );
781809
vhDestroyBuffer( vb );
@@ -807,6 +835,7 @@ UTEST_F( Graphics, UniformBuffers )
807835
state.SetColourAttachment( 0, rt )
808836
.SetViewRect( glm::vec4( 0, 0, 64, 64 ) )
809837
.SetViewClear( VRHI_CLEAR_COLOR, glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f ) )
838+
.SetStateFlags( VRHI_STATE_WRITE_MASK )
810839
.SetVertexBuffer( vb, 0 )
811840
.SetUniform( 0, { "u0", { glm::vec4( 0.0, 1.0, 1.0, 1.0 ) } } ) // Cyan tint
812841
.SetProgram( vhCreateGfxProgram( vs, ps ) );
@@ -848,6 +877,7 @@ UTEST_F( Graphics, PushConstants )
848877
state.SetColourAttachment( 0, rt )
849878
.SetViewRect( glm::vec4( 0, 0, 64, 64 ) )
850879
.SetViewClear( VRHI_CLEAR_COLOR, glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f ) )
880+
.SetStateFlags( VRHI_STATE_WRITE_MASK )
851881
.SetVertexBuffer( vb, 0 )
852882
.SetPushConstants( glm::vec4( 1.0, 0.0, 1.0, 1.0 ) ) // Magenta tint
853883
.SetProgram( vhCreateGfxProgram( vs, ps ) );
@@ -891,6 +921,7 @@ UTEST_F( Graphics, MultipleRenderTargets )
891921
.SetColourAttachment( 1, rt1 )
892922
.SetViewRect( glm::vec4( 0, 0, 64, 64 ) )
893923
.SetViewClear( VRHI_CLEAR_COLOR, glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f ) )
924+
.SetStateFlags( VRHI_STATE_WRITE_MASK )
894925
.SetVertexBuffer( vb, 0 )
895926
.SetProgram( vhCreateGfxProgram( vs, ps ) );
896927

@@ -929,6 +960,7 @@ UTEST_F( Graphics, InstancedRendering )
929960
state.SetColourAttachment( 0, rt )
930961
.SetViewRect( glm::vec4( 0, 0, 64, 64 ) )
931962
.SetViewClear( VRHI_CLEAR_COLOR, glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f ) )
963+
.SetStateFlags( VRHI_STATE_WRITE_MASK )
932964
.SetVertexBuffer( vb, 0 )
933965
.SetProgram( vhCreateGfxProgram( vs, ps ) );
934966

@@ -959,7 +991,7 @@ UTEST_F( Graphics, SamplerModes )
959991
0xFFFF0000, 0xFFFFFFFF // Blue, White
960992
};
961993

962-
vhTexture tex = CreateTestTexture( 2, 2, nvrhi::Format::RGBA8_UNORM );
994+
vhTexture tex = CreateTestTexture( 2, 2, nvrhi::Format::RGBA8_UNORM, VRHI_TEXTURE_NONE );
963995
vhMem* data = vhAllocMem( sizeof( pixels ) );
964996
memcpy( data->data(), pixels, sizeof( pixels ) );
965997
vhUpdateTexture( tex, 0, 0, 1, 1, data );
@@ -987,6 +1019,7 @@ UTEST_F( Graphics, SamplerModes )
9871019
vhState state;
9881020
state.SetColourAttachment( 0, rt )
9891021
.SetViewRect( glm::vec4( 0, 0, 64, 64 ) )
1022+
.SetStateFlags( VRHI_STATE_WRITE_MASK )
9901023
.SetVertexBuffer( vb, 0 )
9911024
.SetTexture( 0, { "t0", -1, tex } )
9921025
.SetProgram( program );
@@ -1034,7 +1067,7 @@ UTEST_F( Graphics, MipmapRendering )
10341067

10351068
// Create a texture with 2 mip levels (2x2 and 1x1)
10361069
vhTexture tex = vhAllocTexture();
1037-
vhCreateTexture2D( tex, glm::ivec2( 2, 2 ), 2, nvrhi::Format::RGBA8_UNORM );
1070+
vhCreateTexture2D( tex, glm::ivec2( 2, 2 ), 2, nvrhi::Format::RGBA8_UNORM, VRHI_TEXTURE_NONE );
10381071

10391072
// Level 0: Red
10401073
uint32_t pixels0[4] = { 0xFF0000FF, 0xFF0000FF, 0xFF0000FF, 0xFF0000FF };
@@ -1072,6 +1105,7 @@ UTEST_F( Graphics, MipmapRendering )
10721105
state.SetColourAttachment( 0, rt )
10731106
.SetViewRect( glm::vec4( 0, 0, 64, 64 ) )
10741107
.SetViewClear( VRHI_CLEAR_COLOR, glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f ) )
1108+
.SetStateFlags( VRHI_STATE_WRITE_MASK )
10751109
.SetVertexBuffer( vb, 0 )
10761110
.SetTexture( 0, { "t0", -1, tex } )
10771111
.SetSampler( 0, { "s0", -1, VRHI_SAMPLER_POINT | VRHI_SAMPLER_UVW_CLAMP } )
@@ -1133,6 +1167,7 @@ UTEST_F( Graphics, MultipleVertexStreams )
11331167
state.SetColourAttachment( 0, rt )
11341168
.SetViewRect( glm::vec4( 0, 0, 64, 64 ) )
11351169
.SetViewClear( VRHI_CLEAR_COLOR, glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f ) )
1170+
.SetStateFlags( VRHI_STATE_WRITE_MASK )
11361171
.SetVertexBuffer( vb0, 0 )
11371172
.SetVertexBuffer( vb1, 1 )
11381173
.SetProgram( program );
@@ -1183,6 +1218,7 @@ UTEST_F( Graphics, VertexBufferOffset )
11831218
state.SetColourAttachment( 0, rt )
11841219
.SetViewRect( glm::vec4( 0, 0, 64, 64 ) )
11851220
.SetViewClear( VRHI_CLEAR_COLOR, glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f ) )
1221+
.SetStateFlags( VRHI_STATE_WRITE_MASK )
11861222
.SetVertexBuffer( vb, 0, 3 * sizeof( Vertex ) ) // Offset to green triangle
11871223
.SetProgram( program );
11881224

@@ -1240,6 +1276,7 @@ UTEST_F( Graphics, IndirectDraw )
12401276
state.SetColourAttachment( 0, rt )
12411277
.SetViewRect( glm::vec4( 0, 0, 64, 64 ) )
12421278
.SetViewClear( VRHI_CLEAR_COLOR, glm::vec4( 0.0f, 0.0f, 0.0f, 1.0f ) )
1279+
.SetStateFlags( VRHI_STATE_WRITE_MASK )
12431280
.SetVertexBuffer( vb, 0 )
12441281
.SetIndirectParams( argBuffer )
12451282
.SetProgram( program );

vrhi.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -682,8 +682,8 @@ typedef uint64_t vhFramebuffer;
682682
//
683683
struct vhState
684684
{
685-
glm::vec4 viewRect = glm::vec4( 0.0f, 0.0f, 0.0f, 0.0f );
686-
glm::vec4 viewScissor = glm::vec4( 0.0f, 0.0f, 0.0f, 0.0f );
685+
glm::vec4 viewRect = glm::vec4( 0.0f, 0.0f, 1.0f, 1.0f );
686+
glm::vec4 viewScissor = glm::vec4( 0.0f, 0.0f, -1.0f, -1.0f );
687687
glm::mat4 viewMatrix = glm::mat4( 1.0f );
688688
glm::mat4 projMatrix = glm::mat4( 1.0f );
689689
std::vector< glm::mat4 > worldMatrix; // worldMatrix[0] is copied into pushConstants[0] if worldMatrix is non-empty.

0 commit comments

Comments
 (0)