Moving viewport transform to vertex shaders.
This commit is contained in:
parent
7b9a804fc0
commit
0efd7b4a62
|
@ -143,23 +143,7 @@ int D3D11GeometryShader::Generate(D3D11VertexShader* vertex_shader,
|
||||||
|
|
||||||
output->Append(
|
output->Append(
|
||||||
"cbuffer geo_consts {\n"
|
"cbuffer geo_consts {\n"
|
||||||
" float4 window;\n" // x,y,w,h
|
"};\n");
|
||||||
" float4 viewport_z_enable;\n" // min,(max - min),?,enabled
|
|
||||||
" float4 viewport_size;\n" // x,y,w,h
|
|
||||||
"};"
|
|
||||||
"float4 applyViewport(float4 pos) {\n"
|
|
||||||
" if (viewport_z_enable.w) {\n"
|
|
||||||
//" pos.x = (pos.x + 1) * viewport_size.z * 0.5 + viewport_size.x;\n"
|
|
||||||
//" pos.y = (1 - pos.y) * viewport_size.w * 0.5 + viewport_size.y;\n"
|
|
||||||
//" pos.z = viewport_z_enable.x + pos.z * viewport_z_enable.y;\n"
|
|
||||||
// w?
|
|
||||||
" } else {\n"
|
|
||||||
" pos.xy = pos.xy / float2(window.z / 2.0, -window.w / 2.0) + float2(-1.0, 1.0);\n"
|
|
||||||
" pos.zw = float2(0.0, 1.0);\n"
|
|
||||||
" }\n"
|
|
||||||
" pos.xy += window.xy;\n"
|
|
||||||
" return pos;\n"
|
|
||||||
"}\n");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -225,11 +209,10 @@ int D3D11RectListGeometryShader::Generate(D3D11VertexShader* vertex_shader,
|
||||||
"void main(triangle VERTEX input[3], inout TriangleStream<VERTEX> output) {\n"
|
"void main(triangle VERTEX input[3], inout TriangleStream<VERTEX> output) {\n"
|
||||||
" for (uint n = 0; n < 3; n++) {\n"
|
" for (uint n = 0; n < 3; n++) {\n"
|
||||||
" VERTEX v = input[n];\n"
|
" VERTEX v = input[n];\n"
|
||||||
" v.oPos = applyViewport(v.oPos);\n"
|
|
||||||
" output.Append(v);\n"
|
" output.Append(v);\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" VERTEX v = input[2];\n"
|
" VERTEX v = input[2];\n"
|
||||||
" v.oPos = applyViewport(v.oPos + input[1].oPos - input[0].oPos);\n"
|
" v.oPos += input[1].oPos - input[0].oPos;\n"
|
||||||
// TODO(benvanik): only if needed?
|
// TODO(benvanik): only if needed?
|
||||||
" v.oPointSize += input[1].oPointSize - input[0].oPointSize;\n");
|
" v.oPointSize += input[1].oPointSize - input[0].oPointSize;\n");
|
||||||
auto alloc_counts = vertex_shader->alloc_counts();
|
auto alloc_counts = vertex_shader->alloc_counts();
|
||||||
|
@ -268,7 +251,6 @@ int D3D11QuadListGeometryShader::Generate(D3D11VertexShader* vertex_shader,
|
||||||
" const uint order[4] = { 0, 1, 3, 2 };\n"
|
" const uint order[4] = { 0, 1, 3, 2 };\n"
|
||||||
" for (uint n = 0; n < 4; n++) {\n"
|
" for (uint n = 0; n < 4; n++) {\n"
|
||||||
" VERTEX v = input[order[n]];\n"
|
" VERTEX v = input[order[n]];\n"
|
||||||
" v.oPos = applyViewport(v.oPos);\n"
|
|
||||||
" output.Append(v);\n"
|
" output.Append(v);\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" output.RestartStrip();\n"
|
" output.RestartStrip();\n"
|
||||||
|
|
|
@ -52,7 +52,10 @@ D3D11GraphicsDriver::D3D11GraphicsDriver(
|
||||||
&buffer_desc, NULL, &state_.constant_buffers.loop_constants);
|
&buffer_desc, NULL, &state_.constant_buffers.loop_constants);
|
||||||
buffer_desc.ByteWidth = (32) * sizeof(int);
|
buffer_desc.ByteWidth = (32) * sizeof(int);
|
||||||
hr = device_->CreateBuffer(
|
hr = device_->CreateBuffer(
|
||||||
&buffer_desc, NULL, &state_.constant_buffers.geo_constants);
|
&buffer_desc, NULL, &state_.constant_buffers.vs_consts);
|
||||||
|
buffer_desc.ByteWidth = (32) * sizeof(int);
|
||||||
|
hr = device_->CreateBuffer(
|
||||||
|
&buffer_desc, NULL, &state_.constant_buffers.gs_consts);
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D11GraphicsDriver::~D3D11GraphicsDriver() {
|
D3D11GraphicsDriver::~D3D11GraphicsDriver() {
|
||||||
|
@ -60,7 +63,8 @@ D3D11GraphicsDriver::~D3D11GraphicsDriver() {
|
||||||
XESAFERELEASE(state_.constant_buffers.float_constants);
|
XESAFERELEASE(state_.constant_buffers.float_constants);
|
||||||
XESAFERELEASE(state_.constant_buffers.bool_constants);
|
XESAFERELEASE(state_.constant_buffers.bool_constants);
|
||||||
XESAFERELEASE(state_.constant_buffers.loop_constants);
|
XESAFERELEASE(state_.constant_buffers.loop_constants);
|
||||||
XESAFERELEASE(state_.constant_buffers.geo_constants);
|
XESAFERELEASE(state_.constant_buffers.vs_consts);
|
||||||
|
XESAFERELEASE(state_.constant_buffers.gs_consts);
|
||||||
delete shader_cache_;
|
delete shader_cache_;
|
||||||
XESAFERELEASE(context_);
|
XESAFERELEASE(context_);
|
||||||
XESAFERELEASE(device_);
|
XESAFERELEASE(device_);
|
||||||
|
@ -193,7 +197,7 @@ int D3D11GraphicsDriver::SetupDraw(XE_GPU_PRIMITIVE_TYPE prim_type) {
|
||||||
if (geometry_shader) {
|
if (geometry_shader) {
|
||||||
context_->GSSetShader(geometry_shader->handle(), NULL, NULL);
|
context_->GSSetShader(geometry_shader->handle(), NULL, NULL);
|
||||||
context_->GSSetConstantBuffers(
|
context_->GSSetConstantBuffers(
|
||||||
0, 1, &state_.constant_buffers.geo_constants);
|
0, 1, &state_.constant_buffers.gs_consts);
|
||||||
} else {
|
} else {
|
||||||
context_->GSSetShader(NULL, NULL, NULL);
|
context_->GSSetShader(NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
@ -491,29 +495,31 @@ int D3D11GraphicsDriver::UpdateState(uint32_t state_overrides) {
|
||||||
}
|
}
|
||||||
context_->RSSetViewports(1, &viewport);
|
context_->RSSetViewports(1, &viewport);
|
||||||
|
|
||||||
//"cbuffer geo_consts {\n"
|
// Viewport constants from D3D11VertexShader.
|
||||||
|
//"cbuffer vs_consts {\n"
|
||||||
//" float4 window;\n" // x,y,w,h
|
//" float4 window;\n" // x,y,w,h
|
||||||
//" float4 viewport_z_enable;\n" // min,(max - min),?,enabled
|
//" float4 viewport_z_enable;\n" // min,(max - min),?,enabled
|
||||||
//" float4 viewport_size;\n" // x,y,w,h
|
//" float4 viewport_size;\n" // x,y,w,h
|
||||||
//"};"
|
//"};"
|
||||||
|
// TODO(benvanik): only when viewport changes.
|
||||||
D3D11_MAPPED_SUBRESOURCE res;
|
D3D11_MAPPED_SUBRESOURCE res;
|
||||||
context_->Map(
|
context_->Map(
|
||||||
state_.constant_buffers.geo_constants, 0,
|
state_.constant_buffers.vs_consts, 0,
|
||||||
D3D11_MAP_WRITE_DISCARD, 0, &res);
|
D3D11_MAP_WRITE_DISCARD, 0, &res);
|
||||||
float* geo_buffer = (float*)res.pData;
|
float* vsc_buffer = (float*)res.pData;
|
||||||
geo_buffer[0] = (float)window_offset_x;
|
vsc_buffer[0] = (float)window_offset_x;
|
||||||
geo_buffer[1] = (float)window_offset_y;
|
vsc_buffer[1] = (float)window_offset_y;
|
||||||
geo_buffer[2] = (float)window_width;
|
vsc_buffer[2] = (float)window_width;
|
||||||
geo_buffer[3] = (float)window_height;
|
vsc_buffer[3] = (float)window_height;
|
||||||
geo_buffer[4] = viewport.MinDepth;
|
vsc_buffer[4] = viewport.MinDepth;
|
||||||
geo_buffer[5] = viewport.MaxDepth - viewport.MinDepth;
|
vsc_buffer[5] = viewport.MaxDepth - viewport.MinDepth;
|
||||||
geo_buffer[6] = 0; // unused
|
vsc_buffer[6] = 0; // unused
|
||||||
geo_buffer[7] = vport_xscale_enable ? 1.0f : 0.0f;
|
vsc_buffer[7] = vport_xscale_enable ? 1.0f : 0.0f;
|
||||||
geo_buffer[8] = viewport.TopLeftX;
|
vsc_buffer[8] = viewport.TopLeftX;
|
||||||
geo_buffer[9] = viewport.TopLeftY;
|
vsc_buffer[9] = viewport.TopLeftY;
|
||||||
geo_buffer[10] = viewport.Width;
|
vsc_buffer[10] = viewport.Width;
|
||||||
geo_buffer[11] = viewport.Height;
|
vsc_buffer[11] = viewport.Height;
|
||||||
context_->Unmap(state_.constant_buffers.geo_constants, 0);
|
context_->Unmap(state_.constant_buffers.vs_consts, 0);
|
||||||
|
|
||||||
// Scissoring.
|
// Scissoring.
|
||||||
// TODO(benvanik): pull from scissor registers.
|
// TODO(benvanik): pull from scissor registers.
|
||||||
|
@ -733,10 +739,14 @@ int D3D11GraphicsDriver::BindShaders() {
|
||||||
context_->VSSetShader(vs->handle(), NULL, 0);
|
context_->VSSetShader(vs->handle(), NULL, 0);
|
||||||
|
|
||||||
// Set constant buffers.
|
// Set constant buffers.
|
||||||
|
ID3D11Buffer* vs_constant_buffers[] = {
|
||||||
|
state_.constant_buffers.float_constants,
|
||||||
|
state_.constant_buffers.bool_constants,
|
||||||
|
state_.constant_buffers.loop_constants,
|
||||||
|
state_.constant_buffers.vs_consts,
|
||||||
|
};
|
||||||
context_->VSSetConstantBuffers(
|
context_->VSSetConstantBuffers(
|
||||||
0,
|
0, XECOUNT(vs_constant_buffers), vs_constant_buffers);
|
||||||
sizeof(state_.constant_buffers) / sizeof(ID3D11Buffer*),
|
|
||||||
(ID3D11Buffer**)&state_.constant_buffers);
|
|
||||||
|
|
||||||
// Setup input layout (as encoded in vertex shader).
|
// Setup input layout (as encoded in vertex shader).
|
||||||
context_->IASetInputLayout(vs->input_layout());
|
context_->IASetInputLayout(vs->input_layout());
|
||||||
|
@ -765,10 +775,13 @@ int D3D11GraphicsDriver::BindShaders() {
|
||||||
context_->PSSetShader(ps->handle(), NULL, 0);
|
context_->PSSetShader(ps->handle(), NULL, 0);
|
||||||
|
|
||||||
// Set constant buffers.
|
// Set constant buffers.
|
||||||
|
ID3D11Buffer* vs_constant_buffers[] = {
|
||||||
|
state_.constant_buffers.float_constants,
|
||||||
|
state_.constant_buffers.bool_constants,
|
||||||
|
state_.constant_buffers.loop_constants,
|
||||||
|
};
|
||||||
context_->PSSetConstantBuffers(
|
context_->PSSetConstantBuffers(
|
||||||
0,
|
0, XECOUNT(vs_constant_buffers), vs_constant_buffers);
|
||||||
sizeof(state_.constant_buffers) / sizeof(ID3D11Buffer*),
|
|
||||||
(ID3D11Buffer**)&state_.constant_buffers);
|
|
||||||
|
|
||||||
// TODO(benvanik): set samplers for all inputs.
|
// TODO(benvanik): set samplers for all inputs.
|
||||||
D3D11_SAMPLER_DESC sampler_desc;
|
D3D11_SAMPLER_DESC sampler_desc;
|
||||||
|
|
|
@ -95,7 +95,8 @@ private:
|
||||||
ID3D11Buffer* float_constants;
|
ID3D11Buffer* float_constants;
|
||||||
ID3D11Buffer* bool_constants;
|
ID3D11Buffer* bool_constants;
|
||||||
ID3D11Buffer* loop_constants;
|
ID3D11Buffer* loop_constants;
|
||||||
ID3D11Buffer* geo_constants;
|
ID3D11Buffer* vs_consts;
|
||||||
|
ID3D11Buffer* gs_consts;
|
||||||
} constant_buffers;
|
} constant_buffers;
|
||||||
} state_;
|
} state_;
|
||||||
|
|
||||||
|
|
|
@ -393,6 +393,28 @@ const char* D3D11VertexShader::Translate(xe_gpu_program_cntl_t* program_cntl) {
|
||||||
"};\n");
|
"};\n");
|
||||||
// TODO(benvanik): add bool/loop constants.
|
// TODO(benvanik): add bool/loop constants.
|
||||||
|
|
||||||
|
// Transform utilities. We adjust the output position in various ways
|
||||||
|
// as we can't do this via D3D11 APIs.
|
||||||
|
output->append(
|
||||||
|
"cbuffer vs_consts : register(b3) {\n"
|
||||||
|
" float4 window;\n" // x,y,w,h
|
||||||
|
" float4 viewport_z_enable;\n" // min,(max - min),?,enabled
|
||||||
|
" float4 viewport_size;\n" // x,y,w,h
|
||||||
|
"};"
|
||||||
|
"float4 applyViewport(float4 pos) {\n"
|
||||||
|
" if (viewport_z_enable.w) {\n"
|
||||||
|
//" pos.x = (pos.x + 1) * viewport_size.z * 0.5 + viewport_size.x;\n"
|
||||||
|
//" pos.y = (1 - pos.y) * viewport_size.w * 0.5 + viewport_size.y;\n"
|
||||||
|
//" pos.z = viewport_z_enable.x + pos.z * viewport_z_enable.y;\n"
|
||||||
|
// w?
|
||||||
|
" } else {\n"
|
||||||
|
" pos.xy = pos.xy / float2(window.z / 2.0, -window.w / 2.0) + float2(-1.0, 1.0);\n"
|
||||||
|
" pos.zw = float2(0.0, 1.0);\n"
|
||||||
|
" }\n"
|
||||||
|
" pos.xy += window.xy;\n"
|
||||||
|
" return pos;\n"
|
||||||
|
"}\n");
|
||||||
|
|
||||||
// Add vertex shader input.
|
// Add vertex shader input.
|
||||||
output->append(
|
output->append(
|
||||||
"struct VS_INPUT {\n");
|
"struct VS_INPUT {\n");
|
||||||
|
@ -472,6 +494,7 @@ const char* D3D11VertexShader::Translate(xe_gpu_program_cntl_t* program_cntl) {
|
||||||
|
|
||||||
// main footer.
|
// main footer.
|
||||||
output->append(
|
output->append(
|
||||||
|
" o.oPos = applyViewport(o.oPos);\n"
|
||||||
" return o;\n"
|
" return o;\n"
|
||||||
"};\n");
|
"};\n");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue